嵌套贪心量词不匹配

时间:2014-05-28 02:22:48

标签: php regex regex-greedy

我注意到一些PCRE正则表达式的奇怪行为,我无法解释。我希望代码:

preg_match('!^.+?(?:/programs/([^?#]+))?.*?$!',
    'http://example.com/programs/drive', $matches);

返回"驱动"作为匹配1.非捕获组之后的[^?#]+?都是贪婪的,那么为什么[^?#]+优先并匹配drive?相反,测试显示,开头的.+?h匹配,最后的.*?与网址的其余部分匹配。

相比之下,代码:

preg_match('!^.+?(?:/programs/([^?#]+).*)?$!',
     'http://example.com/programs/drive', $matches);

按预期工作,并返回drive作为匹配1。

1 个答案:

答案 0 :(得分:3)

这是多么幸福。第一个.+?应用于hhttp之前的字符串开头。这是懒惰的,所以它立即放弃了蝙蝠,(?:/programs/([^?#]+).*)?针对h进行了测试。整个表达式是可选的,因此它也会在字符串开头失败后放弃。最后,应用模式末尾的.*?$,此表达式能够匹配字符串中的所有字符,以便成功匹配。