非贪婪匹配

黑派客     最近更新时间:2020-01-16 05:10:29

677

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

给定一个字符串表示的数字,判断该数字末尾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+后面加个?即可表示非贪婪匹配。我们改写正则表达式如下:

展开阅读全文