否定前瞻不按预期工作

时间:2016-09-26 18:29:28

标签: php regex regex-lookarounds

我有一个奇怪的情况,其中正向前瞻按预期工作,但负向前瞻却没有。请查看以下代码:

<?php

$tweet = "RT @Startup_Collab: @RiseOfRest is headed to OMA & LNK to #showcase our emerging #startup ecosystem. Learn more! https://example.net #Riseof…";

$patterns=array(
    '/#\w+(?=…$)/',
);

$tweet = preg_replace_callback($patterns,function($m)
{
    switch($m[0][0])
    {
        case "#":
            return strtoupper($m[0]);
        break;
    }
},$tweet);


echo $tweet;

我希望匹配任何没有跟…$及其大写的主题标签(实际上它将使用href进行解析,但为了简单起见,现在就是大写的。)

这些是正则表达式及其相应的输出:

'/#\w+(?=…$)/'匹配以…$结尾的任何#标签及大写字母,按预期工作:

RT @Startup_Collab: @RiseOfRest is headed to OMA & LNK to #showcase our emerging #startup ecosystem. Learn more! https://example.net #RISEOF…

'/#\w+(?!…$)/'匹配任何不以…$结尾的主题标签,大写它,不起作用,所有主题标签都是大写的:

RT @Startup_Collab: @RiseOfRest is headed to OMA & LNK to #SHOWCASE our emerging #STARTUP ecosystem. Learn more! https://example.net #RISEOf…

非常感谢您的任何帮助,建议,想法和耐心。

- 天使

1 个答案:

答案 0 :(得分:2)

这是因为回溯符合标签的一部分。使用占有量词来避免回溯到\w+子模式:

/#\w++(?!…$)/
    ^^

请参阅regex demo

现在,匹配了1个或多个字符,(?!…$)否定前瞻仅在这些字符匹配后执行一次。如果存在 false 结果,则不会发生回溯,并且整个匹配失败。

请点击此处possessive quantifiers了解详情。