Matcher在字符串末尾创建额外的组

时间:2014-04-09 18:49:03

标签: java regex matcher

我遇到了java.util.regex.Matcher的奇怪行为。 让我们考虑一下例子:

    Pattern p = Pattern.compile("\\d*");
    String s = "a1b";
    Matcher m = p.matcher(s);
    while(m.find())
    {
        System.out.println(m.start()+" "+m.end());
    }

它产生输出:

0 0
1 2
2 2
3 3

我可以理解除了最后一行之外的所有行。 Matcher从字符串中创建额外的组(3,3)。 但方法start()的javadoc确认:

  

start()返回上一个匹配的起始索引。

点星模式的情况相同:

Pattern p = Pattern.compile(".*");
String s = "a1b";
Matcher m = p.matcher(s);
while(m.find())
{
    System.out.println(m.start()+" "+m.end());
}

输出:

0 3
3 3

但是如果指定行边界

Pattern p = Pattern.compile("^.*$");

输出将是“正确的”:

0 3

有人可以解释我这种行为的原因吗?

1 个答案:

答案 0 :(得分:1)

模式"\\d*"匹配0位或更多位数。同样代表".*"。它匹配除换行符之外的任何字符的0或更多次出现。

您获得的最后一个匹配是字符串末尾的空字符串,位于"b"之后。空字符串满足模式\\d*。如果您将模式更改为\\d+,您将获得预期结果。

同样,模式.*匹配从第一个字符到最后一个字符的所有内容。因此它首先匹配"a1b"。之后,光标位于b"a1b|"之后。现在,matcher.find()再次运行,并在光标处找到零长度字符串,这符合模式.*,因此它将其视为匹配。

它给出"^.*$"的预期输出的原因是最后一个空字符串不满足^锚点。它不在字符串的开头,因此无法匹配。