我注意到一个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
进行测试。整个表达式是可选的,所以它也会在字符串开头匹配失败后放弃。最后,应用模式末尾的.*?$
,该表达式能够匹配字符串中的所有字符,以实现成功的匹配。