嵌套贪婪量词不匹配



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

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

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

相比之下,代码:

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

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

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

最新更新