String.replaceAll(regex) 匹配行為
String.replaceAll(".*", "a") 結果的奇怪觀察in "aa" 引發了有關.* 正規表示式性質的問題。
符合任何內容
.* 符合任何字元序列,甚至是空字串。因此,第一個匹配包含整個輸入字串,促使正規表示式引擎從末尾開始搜尋後續匹配。
但是,.* 也可以符合輸入末尾的空字串。因此,它找到第二個匹配項並將其替換為“a”,從而得到“aa”結果。
使用 . 和 .replaceFirst()
要防止這種行為,請使用 . 相反,因為它需要至少一個字元來匹配。或者,使用 .replaceFirst() 將替換限制為第一次出現。
行為解釋
.* 匹配空字串的事實是奇特的,值得更深入的探索。與大多數正規表示式引擎不同,Java 的正規表示式引擎在第二次與 .* 匹配後在輸入中進一步移動一個字元。這種偏差在下圖中很明顯:
<code class="text"># 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 is 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</code>
但是,值得注意的是,其他正規表示式引擎(如 GNU sed)會在第一次匹配後考慮輸入耗盡。
以上是為什麼 Java 中的 String.replaceAll('.*', 'a') 結果是 'aa' ?的詳細內容。更多資訊請關注PHP中文網其他相關文章!