任何人都可以告诉我为什么
System.out.println("test".replaceAll(".*", "a"));
结果
aa
请注意,以下结果相同:
System.out.println("test".replaceAll(".*$", "a"));
我在java 6& 7并且两者似乎都表现得一样。 我错过了什么或者这是java正则表达式引擎中的错误吗?
答案 0 :(得分:59)
这不是异常现象:.*
可以匹配任何内容。
您要求替换所有出现次数:
.*
也匹配空字符串!因此,它匹配输入末尾的空字符串,并将其替换为a
。使用.+
代替不会出现此问题,因为此正则表达式无法匹配空字符串(它需要至少匹配一个字符)。
或者,使用.replaceFirst()
仅替换第一次出现:
"test".replaceFirst(".*", "a")
^^^^^^^^^^^^
现在,为什么.*
表现得像以及不匹配超过两次(理论上可以),这是一个值得考虑的有趣事情。见下文:
# Before first run
regex: |.*
input: |whatever
# After first run
regex: .*|
input: whatever|
#before second run
regex: |.*
input: whatever|
#after second run: since .* can match an empty string, it it satisfied...
regex: .*|
input: whatever|
# However, this means the regex engine matched an empty input.
# All regex engines, in this situation, will shift
# one character further in the input.
# So, before third run, the situation is:
regex: |.*
input: whatever<|ExhaustionOfInput>
# Nothing can ever match here: out
请注意,@ A.H。注释中的注释,并非所有正则表达式引擎都以这种方式运行。例如,GNU sed
会认为在第一次匹配后它已经耗尽了输入。