什么.*?正则表达式实际上是指

AgA*_*AgA 2 regex perl

我已经使用perl十年了.但最近我对使用它感到困惑.*?正则表达式.

它似乎与最小字符数不匹配.有时会产生不同的结果.

例如,对于这个字符串:aaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmbaaaaaaaaaaaaaaaaaaaaaa和pattern:a.*?b它匹配两组中的完整输入字符串.根据定义,它应该与最后的"ab"相匹配.

ike*_*ami 8

示例缩写为:

'aaab' =~ /a.*?b/
Run Code Online (Sandbox Code Playgroud)

怎么了:

  1. a比赛a.
  2. .*? 匹配可能的最少字符数(0),匹配空字符串.
  3. b无法匹配.⇒回溯
  4. .*? 匹配尽可能少的字符数(1),匹配 a
  5. b无法匹配.⇒回溯
  6. .*? 匹配尽可能少的字符数(2),匹配 aa
  7. b比赛b.
  8. 模式匹配成功.

我试图避免使用非贪婪的修饰符.

'aaab' =~ /a[^a]*b/
Run Code Online (Sandbox Code Playgroud)

如果a真的更复杂,那么可以使用负面的前瞻.

'aaab' =~ /a(?:(?!a).)*b/
Run Code Online (Sandbox Code Playgroud)

  • 同意避免使用非贪婪的修饰符.使用否定字符类或负面预测(它避免回溯)不仅通常更有效,而且还为未来的维护程序员更清楚地记录了您的意图. (2认同)

Tim*_*ker 6

它的意思是

.   # 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>,那么你会得到两个匹配:

  1. <tag> text </tag>
  2. <tag> even more text </tag>

texteven 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)

因为正则表达式引擎从左到右工作.这是正则表达式"不是匹配无上下文语法的最佳工具"的原因之一.