Regex 正则表达式惰性量词断言开始和结束

Regex 正则表达式惰性量词断言开始和结束,regex,match,lazy-evaluation,regex-greedy,Regex,Match,Lazy Evaluation,Regex Greedy,当将正则表达式量化为惰性时,例如\w{2,4}?,当断言为测试的开始和结束时,它是否比其他(贪婪)方法更有效 e、 g.^\w{2,4}$vs^\w{2,4}$测试“12345”和“1234”两者都不会匹配测试字符串,因为您的输入包含5个字符,而您的正则表达式只匹配具有2到4个字符的字符串。使用锚时,不需要此?^.*?$与^.*$的操作相同。我建议您使用^\w{2,4}$而不是^\w{2,4}?$。第二个需要8个步骤才能找到匹配项,而第一个需要5个步骤才能找到匹配项 让我们考虑 1234 /代

当将正则表达式量化为惰性时,例如
\w{2,4}?
,当断言为测试的开始和结束时,它是否比其他(贪婪)方法更有效


e、 g.
^\w{2,4}$
vs
^\w{2,4}$
测试“12345”和“1234”

两者都不会匹配测试字符串,因为您的输入包含5个字符,而您的正则表达式只匹配具有2到4个字符的字符串。使用锚时,不需要此
<代码>^.*?$与
^.*$
的操作相同。我建议您使用
^\w{2,4}$
而不是
^\w{2,4}?$
。第二个需要8个步骤才能找到匹配项,而第一个需要5个步骤才能找到匹配项

让我们考虑<代码> 1234 /代码>作为样本字符串。

  • ^\w{2,4}$

    从一开始,上面的正则表达式将贪婪地匹配从2到4个字符范围内的所有字符,
    $
    锚点断言我们在末尾

  • ^\w{2,4}?$

    但当我们使用它时,它最多匹配两个字符并检查行尾。因为第二个字符旁边没有行尾定位,所以它与第三个字符匹配,并再次检查第三个字符旁边的行尾定位。结果为“否”,因此它将移动到下一个字符并与之匹配。现在检查锚链的末端。是的,这是终点线。如果第四个字符后面有任何字符,则放弃其操作。这就是采取比贪婪的步骤更多步骤的原因

  • 不。贪婪量词和懒惰量词都会产生“回溯”

    但是,在某些情况下,有一种方法不会产生回溯,因此速度更快。它确实有一个非常特殊的行为,并且有许多正则表达式引擎不支持所有格量词(javascript不支持,PCRE不支持)

    正如前面提到的,回溯将不会在这个特定的示例中使用,所有这些表达式

    ^\w{2,5}?$
    ^\w{2,5}$
    ^\w{2,5}+$
    ^\w{2,4}$
    ^\w{2,4}$
    ^\w{2,4}+$

    在匹配字符串12345的时间上没有差异

    见答案


    两者都与测试字符串不匹配。使用锚时,不需要此
    <代码>^.*?$
    ^.*$
    的操作相同。建议您使用
    ^\w{2,4}$
    而不是
    ^\w{2,4}?$
    。第二个需要8个步骤才能找到匹配项,而第一个需要5个步骤才能找到匹配项。你说得对,回溯不会在这个特定的例子中使用。我的意思是“1234”,正如我猜你猜的那样。:)因此,在测试135个字符的字符串时,
    ^/w{2135}$
    的效率远远低于
    ^\w{2135}$
    。这是因为在2个字符之后,每个字符需要+1步,对吗?是的,你是对的。而且它是
    \w
    而不是
    /w
    。您仍然有任何疑问,请单击此链接左侧的regex调试器。是的,意思是“\w”(我正在测试URL)。我不知道regex101有这样的调试器。
    <?php header('Content-Type: text/plain');
    $s = str_repeat("12345\n",1000);
    function a($r){
        global $s;
        $r = '#'.$r.'#m';
        $time_a = (double)microtime(true);
        for($i=0;$i<100000;$i++)preg_match( $r, $s );
        echo "$r\t".( (double)microtime(true) - $time_a )."\n";
    }
    a('^\w{2,5}$');  // 0.093012094497681 ; 0.10101294517517 
    a('^\w{2,5}?$'); // 0.095011949539185 ; 0.09201192855835 
    a('^\w{2,5}+$'); // 0.094011783599854 ; 0.093512058258057
    a('^\w{2,4}$');  // 4.3395512104034   ; 4.3435509204865    
    a('^\w{2,4}?$'); // 4.3420507907867   ; 4.3610541820526    
    a('^\w{2,4}+$'); // 4.3565537929535   ; 4.353052854538     
    // lazy "?" quantifier is slower than greedy