非贪婪匹配

在介绍非贪婪匹配前,我们先看一个简单的问题:

给定一个字符串表示的数字,判断该数字末尾0的个数。例如:

  • "123000":3个0
  • "10100":2个0
  • "1001":0个0

可以很容易地写出该正则表达式:(\d+)(0*),Java代码如下:

feitanlanpipei\_1.png

然而打印的第二个子串是空字符串""

实际上,我们期望分组匹配结果是:

input \d+ 0*
123000 "123" "000"
10100 "101" "00"
1001 "1001" ""

但实际的分组匹配结果是这样的:

input \d+ 0*
123000 "123000" ""
10100 "10100" ""
1001 "1001" ""

仔细观察上述实际匹配结果,实际上它是完全合理的,因为\d+确实可以匹配后面任意个0

这是因为正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配,因此,\d+总是会把后面的0包含进来。

要让\d+尽量少匹配,让0*尽量多匹配,我们就必须让\d+使用非贪婪匹配。在规则\d+后面加个?即可表示非贪婪匹配。我们改写正则表达式如下:

feitanlanpipei\_2.png

因此,给定一个匹配规则,加上?后就变成了非贪婪匹配。

我们再来看这个正则表达式(\d??)(9*),注意\d?表示匹配0个或1个数字,后面第二个?表示非贪婪匹配,因此,给定字符串"9999",匹配到的两个子串分别是"""9999",因为对于\d?来说,可以匹配1个9,也可以匹配0个9,但是因为后面的?表示非贪婪匹配,它就会尽可能少的匹配,结果是匹配了0个9

小结

正则表达式匹配默认使用贪婪匹配,可以使用?表示对某一规则进行非贪婪匹配。

注意区分?的含义:\d??

读后有收获可以支付宝请作者喝咖啡,读后有疑问请加微信群讨论

feitanlanpipei\_3.pngfeitanlanpipei\_4.png

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「方志朋」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

results matching ""

    No results matching ""