我已经使用perl十年了.但最近我对使用它感到困惑.*?正则表达式.
它似乎与最小字符数不匹配.有时会产生不同的结果.
例如,对于这个字符串:aaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmbaaaaaaaaaaaaaaaaaaaaaa和pattern:a.*?b它匹配两组中的完整输入字符串.根据定义,它应该与最后的"ab"相匹配.
示例缩写为:
'aaab' =~ /a.*?b/
Run Code Online (Sandbox Code Playgroud)
怎么了:
a比赛a..*? 匹配可能的最少字符数(0),匹配空字符串.b无法匹配.⇒回溯.*? 匹配尽可能少的字符数(1),匹配 ab无法匹配.⇒回溯.*? 匹配尽可能少的字符数(2),匹配 aab比赛b.我试图避免使用非贪婪的修饰符.
'aaab' =~ /a[^a]*b/
Run Code Online (Sandbox Code Playgroud)
如果a真的更复杂,那么可以使用负面的前瞻.
'aaab' =~ /a(?:(?!a).)*b/
Run Code Online (Sandbox Code Playgroud)
它的意思是
. # match any character except newlines
* # zero or more times
? # matching as few characters as possible
Run Code Online (Sandbox Code Playgroud)
所以
<tag> text </tag> more text <tag> even more text </tag>
Run Code Online (Sandbox Code Playgroud)
正则表达式<tag>(.*)</tag>将立即匹配整个字符串,捕获
text </tag> more text <tag> even more text
Run Code Online (Sandbox Code Playgroud)
在反向引用号1.
如果你匹配<tag>(.*?)</tag>,那么你会得到两个匹配:
<tag> text </tag><tag> even more text </tag>仅text和even more text在反向引用编号1分别被捕获.
如果(感谢Kobi!)你的源文本是
<tag> text <tag> nested text </tag> back to first level </tag>
Run Code Online (Sandbox Code Playgroud)
然后你会发现它<tag>(.*)</tag>再次匹配整个字符串,但<tag>(.*?)</tag>会匹配
<tag> text <tag> nested text </tag>
Run Code Online (Sandbox Code Playgroud)
因为正则表达式引擎从左到右工作.这是正则表达式"不是匹配无上下文语法的最佳工具"的原因之一.