贪婪匹配 vs 懒惰(非贪婪)匹配

量词默认贪婪;量词后面加 ? 变成懒惰。

贪婪:满足整体匹配的前提下,拿尽可能多字符

懒惰:满足整体匹配的前提下,拿尽可能少字符

1. 贪婪 a.*b

文本:aabab

  • a:匹配第一个a
  • .*:任意字符,0或多次,贪婪,尽可能吞后面所有字符
  • b:需要找到一个b。 它先一口气吞完全部:aabab,然后发现末尾是b,匹配成功。 结果:整个 aabab

疑问:为什么不匹配 aab 就停下来? 因为贪婪规则:只要整个正则能匹配成功,它就会尽量拿更长的字符串。引擎是从后往前回溯尝试,优先最长匹配。

2. 懒惰 a.*?b

文本:aabab

  • a 匹配第一个a
  • .*?:任意字符,0或多次,懒惰,尽量少拿
  • 只要找到一个b,立刻停止这一轮匹配。

第一轮匹配: a + ab + b → aab(第一个b就停下)

继续往后找,第二轮: a + 空 + b → ab

总共两个匹配结果:aabab

3. 哪些量词可以加 ? 变成懒惰

贪婪懒惰
* 任意数量*?
+ 至少1次+?
? 0或1次??
{n,m} n~m次{n,m}?
{n,} n次以上{n,}?

注意:这里的 ? 不是分支/可选字符,是修饰量词,改变量词的贪婪属性! 两个完全不一样的概念,不要混淆。

4. 经典例子:HTML标签

文本:<div>hello</div><div>world</div>

贪婪正则:<div>.*</div> 匹配结果:<div>hello</div><div>world</div> 一口气抓到最后一个 </div>

懒惰正则:<div>.*?</div> 匹配结果1:<div>hello</div> 匹配结果2:<div>world</div> 找到第一个 </div> 就停止当前匹配。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注