Questa non è un'anomalia: .*
può corrispondere a qualsiasi cosa.
vi chiediamo di sostituire tutte le ricorrenze:
- la prima occorrenza fa corrispondere l'intera stringa, il motore regex inizia quindi dalla fine dell'input per la prossima partita;
- ma
.*
corrisponde anche a una stringa vuota! Corrisponde quindi a una stringa vuota alla fine dell'input e la sostituisce con a
.
L'utilizzo di .+
invece non presenta questo problema poiché questa espressione regolare non può corrispondere a una stringa vuota (richiede almeno un carattere per la corrispondenza).
In alternativa, utilizzare .replaceFirst()
per sostituire solo la prima occorrenza:
"test".replaceFirst(".*", "a")
^^^^^^^^^^^^
Ora, perché .*
si comporta come lo fa e non corrisponde più di due volte (teoricamente potrebbe) è una cosa interessante da prendere in considerazione . Vedi sotto:
# 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 it 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
Si noti che, come @ A.H. note nei commenti, non tutti i motori regex si comportano in questo modo. GNU sed
per esempio considererà che ha esaurito l'input dopo la prima corrispondenza.
concordato. Questo vale anche per Perl. 'perl -le '$ x =" test "; $ x = ~ s /.*/ a/g; stampa $ x'' produce "aa". –
@ChrisDolan: 'sed' produce solo' a', ma dubito che sia un bug. :-) –
@ A.H. Sì, in effetti ... Devo leggere di nuovo "Mastering Regular Expressions" – fge