跳到主要内容

5.3 防止过度匹配

? 只能匹配零个或一个字符, {n}{m,n} 也有一个重复次数的上限;换句话说,这几种语法所定义的重复次数都是有限的。但 *+ 都是没有重复次数限制的,这样就会出现过度匹配的的现象。

到目前为止,我们选用的例子都不存在过度匹配的问题,但请尝试下面的例子:

<b>.*</b>
在工具中查看
<b>是粗体</b>,这<b>也是粗体</b>

我们本意是要使用 <b>.*</b> 匹配“<b>是粗体</b>“和”<b>也是粗体</b>”两个结果,但结果却把“<b>”到最后一个“</b>”之间的所有内容全部匹配了出来。虽然我们需要的内容已经被匹配了出来,但我们不需要的“,这”也被同时匹配了出来,这就是过度匹配。

为什么会这样?因为 *+{n,} 都是“贪婪型”的元字符(模式),它们在进行匹配时会多多益善而不是适可而止。它们会尽可能地从一段文本的开头一直匹配到这段文本的未尾,而不是从这段文本的开头匹配到第一个匹配时为止。

在不需要这种“贪婪行为”的时候该怎么办?答案是使用这些元字符的“懒惰型”版本,“懒惰型”版本的匹配行为和贪婪匹配行为相反,懒惰匹配会尽可能匹配最少的字符。

要如何进入懒惰匹配呢?只需要在 *+{n,} 后面添加一个 ? ,看下面这个例子:

<b>.*?</b>
在工具中查看
<b>是粗体</b>,这<b>也是粗体</b>

这个例子比上面的例子中的模式在 .* 后面多了一个 ? ,匹配结果正是我们需要的两个结果。

注意

教程里面的大多数例子使用的都是”贪婪型“的模式,这么做的出发点是为了让那些示例模式尽可能的简明易懂。在实际工作中,请务必根据具体情况来使用”贪婪型“或”懒惰型“模式。

该内容基于 《正则表达式必知必会》 二度创作
转载请遵守原作者相关协议并注明本页地址
https://iamhefang.cn/tutorials/正则表达式/第五章-重复匹配/5.3-防止过度匹配