请解释*贪婪量词的工作原理

时间:2015-11-19 16:00:04

标签: java regex

Pattern ptn  = Pattern.compile("a*");
Matcher mtch  = ptn.matcher("bbaac");
if(mtch.find()){
    System.out.println(mtch.group());
}

输出 - 不打印任何内容

Pattern ptn  = Pattern.compile("a+");
Matcher mtch  = ptn.matcher("bbaac");
if(mtch.find()){
    System.out.println(mtch.group());
}

输出 - aa

我知道这是一个非常简单的问题,但我仍然对看到*+的行为感到困惑(两者都是贪婪的量词)。 请让我知道为什么在第一种情况下输出不打印,a*贪婪它应该返回aa作为匹配。

2 个答案:

答案 0 :(得分:8)

你的代码中唯一错误的是你没有遍历所有找到的匹配器的子序列。

while (mtch.find()) { // <-- not if here
    System.out.println(mtch.group());
}

模式"a*"将匹配两个空字符串,然后在您的字符串中匹配"aa",因为它是预期的,因为*量词允许零次出现。但是,+量词与空字符串不匹配,因为它匹配一个或多个出现(tutorial about quantifiers)。

 b b a a c
^ ^  ^  ^ ^   <-- matches for case of *

答案 1 :(得分:3)

问题是有5个匹配,你只检查第一个是空字符串,因为a*可以匹配一个空字符串(更准确地说,它匹配字符前的空格)它无法匹配并且在字符串的末尾。)

使用while代替if

请参阅IDEONE demo

String s = "bbaac";
Pattern pattern = Pattern.compile("a*");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(0)); 
} 

匹配数为5:

  • 第一个b
  • 之前的空字符串
  • 第二个b
  • 之前的空字符串
  • aa
  • c
  • 之前的空字符串
  • c后的空字符串(结尾)。

使用a++量词意味着 1次或更多次,不会提取空匹配,只会获得aa

请参阅empty strings on regex101.com

enter image description here