量词默认贪婪;量词后面加 ? 变成懒惰。
贪婪:满足整体匹配的前提下,拿尽可能多字符
懒惰:满足整体匹配的前提下,拿尽可能少字符
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
总共两个匹配结果:aab、ab
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> 就停止当前匹配。
Previous: 内联注释 (?#comment)