首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String.replaceAll(正则表达式)进行两次相同的替换

String.replaceAll(正则表达式)进行两次相同的替换
EN

Stack Overflow用户
提问于 2011-12-22 21:07:02
回答 1查看 2.1K关注 0票数 43

有人能告诉我为什么吗?

代码语言:javascript
复制
System.out.println("test".replaceAll(".*", "a"));

结果:

代码语言:javascript
复制
aa

请注意,下面的结果是相同的:

代码语言:javascript
复制
System.out.println("test".replaceAll(".*$", "a"));

我已经在java6和7上测试过了,看起来两者的表现是一样的。我是不是遗漏了什么,或者这是java regex引擎中的一个bug?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-12-22 21:10:26

这不是异常:.*可以匹配任何内容。

您请求替换所有匹配项:

  • 第一次匹配整个字符串,因此正则引擎从下一次匹配的输入末尾开始;
  • .*也匹配空字符串!因此,它匹配输入末尾的空字符串,并将其替换为a.

使用.+不会出现这个问题,因为这个正则表达式不能匹配空字符串(它需要至少一个字符才能匹配)。

或者,使用.replaceFirst()仅替换第一个匹配项:

代码语言:javascript
复制
"test".replaceFirst(".*", "a")
       ^^^^^^^^^^^^

现在,为什么.*的行为是这样的,并且匹配不超过两次(理论上是可以的),这是一个值得考虑的有趣的事情。如下所示:

代码语言:javascript
复制
# 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会认为它在第一次匹配后耗尽了输入。

票数 64
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8604286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档