Ce n'est pas une anomalie: .*
peut correspondre à quoi que ce soit.
Vous vous demandez pour remplacer toutes les occurrences:
- la première occurrence correspond à l'ensemble de la chaîne, le moteur d'expressions régulières commence donc à partir de la fin de l'entrée pour le prochain match;
- mais
.*
correspond à une chaîne vide! Par conséquent, elle correspond à une chaîne vide à la fin de la saisie, et le remplace par a
.
À l'aide de .+
plutôt présentent pas ce problème car cette expression ne peut pas correspondre à une chaîne vide (il faut au moins un caractère de correspondance).
Alors, pourquoi est - .*
se comporte comme il le fait et ne correspond pas à plus de deux fois (il pourrait théoriquement) est une chose intéressante à considérer. Voir ci-dessous:
# 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
Notez que, comme @A. H. notes dans les commentaires, pas tous les regex moteurs se comportent de cette façon. GNU sed
, par exemple, considèrent qu'il a épuisé l'entrée après le premier match.