Gelagat Padanan String.replaceAll(regex)
Pemerhatian ingin tahu bahawa String.replaceAll(".*", "a") terhasil dalam "aa" menimbulkan persoalan tentang sifat .* regex.
Memadankan Apa-apa
.* sepadan dengan mana-mana jujukan aksara, walaupun rentetan kosong. Oleh itu, padanan pertama merangkumi keseluruhan rentetan input, menggesa enjin regex untuk mencari padanan berikutnya bermula dari penghujung.
Walau bagaimanapun, .* juga boleh memadankan rentetan kosong pada penghujung input. Oleh itu, ia mencari padanan kedua dan menggantikannya dengan "a", yang membawa kepada keputusan "aa".
Menggunakan . dan .replaceFirst()
Untuk mengelakkan tingkah laku ini, gunakan . sebaliknya, kerana ia memerlukan sekurang-kurangnya satu aksara untuk dipadankan. Sebagai alternatif, gunakan .replaceFirst() untuk mengehadkan penggantian kepada kejadian pertama.
Penjelasan Tingkah Laku
Fakta bahawa .* sepadan dengan rentetan kosong adalah pelik dan patut diterokai lebih mendalam . Tidak seperti kebanyakan enjin regex, enjin regex Java mengalihkan satu aksara lebih jauh dalam input selepas padanan kedua dengan .*. Penyimpangan ini jelas dalam ilustrasi berikut:
<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>
Walau bagaimanapun, perlu diperhatikan bahawa enjin regex lain seperti GNU sed menganggap input telah habis selepas perlawanan pertama.
Atas ialah kandungan terperinci Mengapakah String.replaceAll(\".*\", \"a\") menghasilkan \"aa\" dalam Java?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!