2011-12-29 52 views
6

可能重複:
Java regex anomaly?無法理解String.replaceAll非貪婪行爲

爲什麼下面的測試失敗任何想法(返回 「XX」 代替 「X」)我不想做"^.*$" ....我想了解這種行爲。 任何線索?

+0

什麼'「xyz」.replaceAll(「。*」,「x」)'return? – robert 2011-12-29 19:38:51

+0

@robert它返回'「xx」'。 – 2011-12-29 19:40:22

+0

@JackEdmonds爲什麼'「xx」'而不是'「xxx」'? – user219882 2011-12-29 20:02:00

回答

9

是的,它與this question中描述的完全一樣!

.*將首先在輸入端匹配整個輸入,但隨後又一個空字符串...

讓我們用象徵的|正則表達式引擎和輸入與<...>在你的榜樣。

  • 輸入:<xyz>;
  • 正則表達式引擎,在第一次運行之前:<|xyz>;
  • 正則表達式引擎,第一次運行後:<xyz|>(匹配文本:「xyz」);
  • 正則表達式引擎,第二次運行後:<xyz>|(匹配的文本:「」)。

並非所有的正則表達式引擎都這樣。不過,Java確實如此。 perl也是如此。作爲一個反例,sed將在步驟3的輸入結束後將其光標定位。

現在,您還必須瞭解一件至關重要的事情:正則表達式引擎在遇到零長度匹配時總是前進一個字符。否則,請考慮如果您嘗試用'a'替換'^'會發生什麼情況:'^'與某個位置匹配,因此是零長度匹配。如果引擎沒有前進一個字符,那麼「x」將被替換爲「ax」,這將替換爲「aax」等。因此,在第二次匹配之後,Java的正則表達式引擎推進一個「字符「......其中沒有任何:處理結束。

+0

但它不是貪婪匹配嗎? – ekeren 2011-12-29 19:51:35

+0

嗯,它很貪婪,不是嗎?請記住'*'表示「** ZERO **或更多」。所以,'。*'完全滿足於一個空字符串! – fge 2011-12-29 19:55:19

+0

編輯後,我明白了--java迭代它的發現......當它到達最後一個字符時,它也會導致匹配(空字符匹配......)謝謝! – ekeren 2011-12-29 19:56:59

0
@Test 
public void testReplaceAll(){ 
    assertEquals("x", "xyz".replaceAll(".+", "x")); 
} 

可能會做的伎倆,因爲這需要一個或多個字符,所以沒有阻止,其中*可能匹配零個字符,並以「X」代替它的行爲。