【问题标题】:Java regexp - adding parenthesis makes it greedy?Java regex - 添加括号使其变得贪婪?
【发布时间】:2017-01-06 19:06:35
【问题描述】:
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. [编辑,稍后添加]为什么第一种情况下空字符串不匹配?

【问题讨论】:

    标签: java regex regex-greedy


    【解决方案1】:

    为了使量词(?*+{n,m})不情愿(非贪婪或懒惰),它必须后跟 ?。因此,\\d{1,2}? 模式是不情愿的。

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

    1. 一组(\\d{1,2}) 包含一个带有贪婪量词{1,2} 的模式,
    2. 后跟? 贪心量词。

    因此,(\\d{1,2})? 是贪婪的,因为 ? 不会立即跟在量词后面(中间有一个括号将分组关闭),因此它确实 strong> 充当不情愿的正则表达式的元字符。

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

    【讨论】:

    • 由于网址的原因,我已经对这个答案投了赞成票,但你能详细说明一下这个话题吗?
    • 是的,即使我会要求您进一步详细说明。
    • 刚刚编辑了问题,为什么第一种情况下空字符串不匹配?
    • @dharm0us 没错。 ? 紧跟在量词之后只会使量词变得懒惰。
    • @dharm0us 我相信 AR 现在已经足够详细了。如果你能接受这个答案,那就太好了:)
    【解决方案2】:

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

    \d{1,2}
    

    这本质上是贪婪的,它将匹配min(即1)和max(即2)之间的尽可能多的字符。

    所以对于我们的输入09,它只会匹配09

    现在让我们懒惰使用:

    \d{1,2}?
    

    这将使其尽可能少地。因此,对于相同的输入,它将第一次匹配0,第二次匹配9(因为您使用的是while 循环)。

    现在是第三种情况:

    (\d{1,2})?
    

    匹配 0 或 1 次出现的贪婪 \d{1,2},即匹配 \d{1,2} 或不匹配。

    所以对于相同的输入,它会匹配:

    1. 09
    2. 空字符串

    这是因为我们通过将? 放在(...) 之外来使整个组可选

    【讨论】:

      猜你喜欢
      • 2021-09-08
      • 2023-04-06
      • 1970-01-01
      • 2018-10-12
      • 2020-03-15
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      • 2012-06-27
      相关资源
      最近更新 更多