Regex 正则表达式匹配重复组{0,2}或{0,4},但{0,3}不匹配';T

Regex 正则表达式匹配重复组{0,2}或{0,4},但{0,3}不匹配';T,regex,pcre,Regex,Pcre,首先,这是使用preg 我试图匹配的字符串: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp 我的正则表达式及其匹配项: (\S*\s*){0,1}\S*p = "d xp" (\S*\s*){0,2}\S*p = "c d xp" (\S*\s*){0,3}\S*p = NO MATCH (expecting "b c d xp" (\S*\s*){0,4}\S*p = entire string (\S*\s*){0,5}\S*p = entire

首先,这是使用preg

我试图匹配的字符串:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp
我的正则表达式及其匹配项:

(\S*\s*){0,1}\S*p = "d xp"
(\S*\s*){0,2}\S*p = "c d xp"
(\S*\s*){0,3}\S*p = NO MATCH (expecting "b c d xp"
(\S*\s*){0,4}\S*p = entire string
(\S*\s*){0,5}\S*p = entire string
奇怪的是,如果我去掉一个“a”,它就会工作。而且,
(\S*\S*){0,3}\Sp
(\S*\S){0,3}\S*p
两者都起作用

有人能解释为什么第三个案例的结果不是“b c d xp”,而是没有匹配吗

蒂亚

好问题

我尝试了另一种同样具有Perl重新语法的语言Ruby,它返回了预期的字符串:

$ irb
>> s='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp'
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa b c d xp"
>> s[/(\S*\s*){0,3}\S*p/]
=> "b c d xp"
这让我觉得你发现了一个翻译错误

但我们现在知道了

  • 你的回复是正确的,你对结果的期望也是正确的
  • PHP对回溯有限制,问题是您的表达式达到了限制。Ruby只是不检查,或者有不同的限制
preg\u last\u error()
返回preg\u BACKTRACK\u LIMIT\u error,因此增加BACKTRACK LIMIT可能会解决此问题。试一试

 ini_set('pcre.backtrack_limit', 500000);

m/(\S*\S*){0,3}\S*p/
在测试字符串中工作,顺便说一句。。。是否需要使用
*
而不是
+
?我用更少的探针就能得到你想要的匹配?例如,
m/(\S+\S+{0,3}\S+p/
在3081个探测中匹配
bcd xp
,而
m/(\S*\S*){0,3}\S*p/
在1200222个探测中产生相同的匹配!我会报告这是一个错误。它在PCRE(7.8版)上匹配,但在我的PHP5.2.6或5.3.0(使用PCRE进行preg_uu匹配函数)中不匹配。太棒了。非常感谢你!这让我快发疯了。