当将正则表达式量化为惰性时,例如\w{2,4}?
,在断言作为测试的开始和结束时,它是否比其他(贪婪)效率更高或更低?
e.g。 ^\w{2,4}?$
vs ^\w{2,4}$
测试' 12345' ' 1234'
答案 0 :(得分:3)
两者都不匹配您的测试字符串,因为您的输入包含5个字符,其中正则表达式仅匹配具有2到4个字符的字符串。使用锚点时,不需要?
。 ^.*?$
与^.*$
的作用相同。我建议您使用^\w{2,4}$
代替^\w{2,4}?$
。第二个步骤需要8个步骤来找到匹配,其中第一个将采取5个步骤来找到匹配。
让我们将1234
视为示例字符串。
^\w{2,4}$
从一开始,上面的正则表达式将匹配所有字符,其中贪婪地包含2到4个字符,$
锚点断言我们在最后。
^\w{2,4}?$
但是当我们使用它时,它会匹配两个字符并检查该行的结尾。因为第二个字符旁边没有行锚点的末尾,所以它与第三个字符匹配,并再次检查第三个字符旁边的行锚点的结尾。结果为否,因此它移动到下一个字符并匹配它。现在它检查线锚的结束。是的,它已经结束了。如果第四个字符后面有任何字符,则丢弃它的操作。这是采取比贪婪步骤更多步骤的原因。
答案 1 :(得分:0)
<击> 不会。贪婪和懒惰的量词都会产生“回溯”。
但是,possessive quantifier "+"不会创建回溯,因此在某些情况下会更快。它确实有一个非常具体的行为,并且有许多正则表达式引擎不支持占有量词(javascript没有,PCRE会这样做)
作为Avinash Raj精神错误,此特定示例中不会使用回溯,以及所有这些表达式
^\w{2,5}?$
^\w{2,5}$
^\w{2,5}+$
^\w{2,4}?$
^\w{2,4}$
^\w{2,4}+$
在匹配字符串12345的时间上没有区别
击>
请参阅Avinash Raj's answer回答。
<?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