阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

非贪婪匹配

30次阅读
没有评论

共计 1264 个字符,预计需要花费 4 分钟才能阅读完成。

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

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

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

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

import java.util.regex.*;

public class Main {public static void main(String[] args) {Pattern pattern = Pattern.compile("(\\d+)(0*)");
        Matcher matcher = pattern.matcher("1230000");
        if (matcher.matches()) {System.out.println("group1=" + matcher.group(1)); // "1230000"
            System.out.println("group2=" + matcher.group(2)); // ""
        }
    }
}

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

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

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+ 后面加个 ? 即可表示非贪婪匹配。我们改写正则表达式如下:

import java.util.regex.*;

public class Main {public static void main(String[] args) {Pattern pattern = Pattern.compile("(\\d+?)(0*)");
        Matcher matcher = pattern.matcher("1230000");
        if (matcher.matches()) {System.out.println("group1=" + matcher.group(1)); // "123"
            System.out.println("group2=" + matcher.group(2)); // "0000"
        }
    }
}

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

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

小结

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

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

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计1264字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中