Wej*_*ejn 7 java regex replaceall
我正在编写使用的代码,Matcher#replaceAll并发现以下结果非常令人困惑:
Pattern.compile("(.*)").matcher("sample").replaceAll("$1abc");
Run Code Online (Sandbox Code Playgroud)
现在,我希望输出可以,sampleabc但Java会引发我的注意sampleabcabc.
有人有什么想法吗?
现在,当然,当我锚定模式(^(.*)$)时,问题就消失了.我仍然不知道为什么地狱会replaceAll做那样的双重替换.
并加上侮辱伤害,遵循以下代码:
Pattern.compile("(.*)").matcher("sample").replaceFirst("$1abc")
Run Code Online (Sandbox Code Playgroud)
按预期工作,只返回sampleabc.
由于某种原因,它看起来像输入末尾的空字符串匹配.(我可以看出为什么会匹配;我很感兴趣它只匹配一次而且只有一次.)
如果replaceAll("$1abc")改为replaceAll("'$1'abc")结果是'sample'abc''abc.
请注意,如果您更改(.*)为(.+)然后它可以正常工作,因为它必须匹配至少一个字符.
该代码确认诊断:
Matcher matcher = Pattern.compile("(.*)").matcher("sample");
while (matcher.find()) {
System.out.printf("%d to %d\r\n",
matcher.start(),
matcher.end());
}
Run Code Online (Sandbox Code Playgroud)
......哪个输出:
0 to 6
6 to 6
Run Code Online (Sandbox Code Playgroud)
这里有两件事可以解释为什么会发生这种情况:
(.*) 将成功匹配空字符串.因此,在"sample"匹配整个字符串之后,在该字符串之后尝试另一个匹配e.即使没有剩下的字符,匹配也会成功,并且会发生第二次替换.
由于正则表达式引擎将始终向前移动,因此不会发生其他替换.在最后一个字符是有效的起始索引之后,空字符串将匹配一次,但在匹配空字符串之后,正则表达式引擎没有更多有效的起始位置来尝试匹配.
作为向正则表达式添加字符串锚的开头的替代方法,您可以修改正则表达式,使其通过更改(.*)为匹配一个或多个字符(.+).