Java regexp - 添加括号使它变得贪婪?

时间:2017-01-06 19:06:36

标签: java regex regex-greedy

public void name() throws Exception {
        Pattern p = Pattern.compile("\\d{1,2}?");
        String input = "09";
        Matcher m = p.matcher(input);
        StringBuffer sb = new StringBuffer();
        while(m.find()) {
            System.out.println("match = "+m.group());
        }
    }

上述方法的输出是:

match = 0
match = 9

现在,我只是在正则表达式中添加括号:

public void name() throws Exception {
        Pattern p = Pattern.compile("(\\d{1,2})?");
        String input = "09";
        Matcher m = p.matcher(input);
        StringBuffer sb = new StringBuffer();
        while(m.find()) {
            System.out.println("match = "+m.group());
        }
    }

输出变为:

match = 09
match = 
  1. 为什么括号会在此处匹配贪婪
  2. [编辑,稍后补充]为什么第一种情况下空字符串不匹配?

2 个答案:

答案 0 :(得分:6)

为了量词(<div class="card"> <a href="#"> <div class="background-container"> <div class="background" style="background: url('https://unsplash.it/300/200/?random') no-repeat; background-size: cover; background-position: center;"></div> </div> </a> <a href="#" class="headline link--no-decor"> <h2>Headline</h2> </a> </div>?*+)不情愿(非贪婪或懒惰),必须跟着一个{n,m}。因此,模式?是不情愿的。

另一方面,\\d{1,2}?两级贪婪量词组成

  1. 包含贪婪量词(\\d{1,2})?的模式的小组(\\d{1,2})
  2. 后跟{1,2}贪心量词。
  3. 因此,?是贪婪的,因为(\\d{1,2})?不会立即跟随量词(两者之间有一个用于关闭组的括号),因此它充当不情愿的正则表达式的元字符。

    请参阅this page about quantifiers作为参考。

答案 1 :(得分:1)

让我们从简单的量词正则表达式开始:

nil

贪婪本质上是\d{1,2} (即min)和1之间匹配的字符数尽可能多(即max )。

因此,对于我们的输入2,它只会匹配09

现在让我们使用:

使其懒惰
09

这将使 成为。因此,对于相同的输入,它将首次匹配\d{1,2}? 并且第二次匹配0(因为您使用的是9循环)。

现在第3例:

while

它匹配0或1次贪婪(\d{1,2})? ,这意味着匹配\d{1,2}或者什么都不匹配。

因此,对于相同的输入,它将匹配:

  1. \d{1,2}
  2. 空字符串
  3. 这是因为我们将09放在?

    之外,使整个群组成为可选的