String.replaceAll(regex) の一致動作
String.replaceAll(".*", "a") の結果という興味深い観察"aa" では、.* 正規表現の性質について疑問が生じます。
Matching Anything
.* は、空の文字列を含む任意の文字シーケンスと一致します。したがって、最初の一致には入力文字列全体が含まれ、正規表現エンジンは末尾から開始して以降の一致を検索します。
ただし、.* は入力の末尾にある空の文字列と一致することもあります。したがって、2 番目の一致を見つけて「a」に置き換え、「aa」の結果が得られます。
を使用します。 および .replaceFirst()
この動作を防ぐには、 を使用します。 少なくとも 1 つの文字が一致する必要があるためです。あるいは、 .replaceFirst() を使用して、置換を最初の出現に制限します。
動作の説明
.* が空の文字列に一致するという事実は独特であり、より深く調査する価値があります。 。ほとんどの正規表現エンジンとは異なり、Java の正規表現エンジンは .* との 2 回目の一致の後、入力内の 1 文字をさらにシフトします。この逸脱は、次の図で明らかです:
<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 中国語 Web サイトの他の関連記事を参照してください。