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