我遇到了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
有人可以解释我这种行为的原因吗?
答案 0 :(得分:1)
模式"\\d*"
匹配0位或更多位数。同样代表".*"
。它匹配除换行符之外的任何字符的0或更多次出现。
您获得的最后一个匹配是字符串末尾的空字符串,位于"b"
之后。空字符串满足模式\\d*
。如果您将模式更改为\\d+
,您将获得预期结果。
同样,模式.*
匹配从第一个字符到最后一个字符的所有内容。因此它首先匹配"a1b"
。之后,光标位于b
:"a1b|"
之后。现在,matcher.find()
再次运行,并在光标处找到零长度字符串,这符合模式.*
,因此它将其视为匹配。
它给出"^.*$"
的预期输出的原因是最后一个空字符串不满足^
锚点。它不在字符串的开头,因此无法匹配。