Ao investigar a diferença semântica entre quantificadores com base em comprimento e contagem, notei que a expressão regular do Python 3 deu resultados diferentes para as 2 expressões regulares a seguir (observe os quantificadores +
e *
:
Python 3.10.16 (main, Dec 7 2024, 13:31:33) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.sub('(.{4,5})+', '-', '1234123412341234')
'-4'
>>> re.sub('(.{4,5})*', '-', '1234123412341234')
'--4-'
>>>
E consegui reproduzir isso em PHP, provavelmente porque ambos usam PCRE por trás:
$ php -a
Interactive shell
php > echo preg_replace('/(.{4,5})+/', '-', '1234123412341234');
-4
php > echo preg_replace('/(.{4,5})*/', '-', '1234123412341234');
--4-
php >
Por quê?
O Python não usa PCRE, então não é isso.
(.{4,5})+
primeiro corresponde a "12341", depois se estende para incluir "23412", depois se estende para incluir "34123". Não pode fazer mais, então os primeiros 15 caracteres são substituídos por "-". Não pode corresponder ao "4" final, então ele é deixado sozinho.
(.{4,5})*
corresponde aos primeiros 15 caracteres da mesma forma. Mas então fica com um "4" final. E a string vazia corresponde , porque
*
significa 0 ou mais correspondências, e 0 conta. Então você obtém um segundo "-". O próprio "4" final não corresponde, então é deixado sozinho. Então a string vazia após o "4" final corresponde (0 vezes novamente), então você obtém um "-" final.