18

可能重复:
String.replaceAll() 异常与正则表达式中的贪婪量词 正则表达式中的
奇怪行为

尽管

"a".replaceAll("a", "b")
"a".replaceAll("a+", "b")
"a".replaceAll("a+?", "b")

全部返回b,为什么

"a".replaceAll("a*", "b")

返回bb

"a".replaceAll("a*?", "b")

返回bab

4

3 回答 3

22
"a".replaceAll("a*", "b")

首先替换ab,然后将指针移过b。然后它匹配字符串的结尾,并替换为b. 由于它匹配了一个空字符串,它使指针前进,从字符串中掉出,然后结束,结果是bb.

"a".replaceAll("a*?", "b")

first 匹配字符串的开头并替换为b. 它不匹配,a因为?ina*?表示“非贪婪”(尽可能少匹配)。由于它匹配一个空字符串,它推进指针,跳过a。然后它匹配字符串的结尾,替换为b并退出字符串,导致bab. 最终结果与您所做的相同"a".replaceAll("", "b")

于 2013-02-04T17:23:39.320 回答
5

发生这种情况是因为零宽度匹配。


"a".replaceAll("a*", "b")

将匹配两次:

  1. 在字符串的开头尝试匹配,贪婪*将其a作为匹配项。
  2. 前进到字符串中的下一个位置(现在在字符串的末尾),在那里尝试匹配,空字符串匹配。

    " a "
     \| \___ 2. match empty string
      \_____ 1. match "a"
    


"a".replaceAll("a*?", "b")

还将匹配两次:

  1. 在字符串的开头尝试匹配,非贪婪*?匹配空字符串而不消耗a.
  2. 前进到字符串中的下一个位置(现在在字符串的末尾),尝试在那里匹配,空字符串匹配。

    " a "
     \  \___ 2. match empty string
      \_____ 1. match empty string
    
于 2013-02-04T17:25:08.993 回答
1

"a".replaceAll("a*", "b")

* - 对于 0 或更多,所以在 `a*` 中
1. a - replaced by b
2. * - is also true as empty string is true for *,so, replaced by b 

并且在"a".replaceAll("a*?", "b")

1. *? - makes anything non-greedy means it makes regrex to match as little
        as possible,
2. so,the pre and post empty string would be replaced by "b" and 
   as a*? is non-greedy, it will not replace it 
于 2013-02-04T17:26:54.357 回答