Quantificadores Gulosos e Preguiçosos
Aprenda como funcionam os quantificadores gulosos e preguiçosos em expressões regulares JavaScript: o modo guloso consome o máximo e retrocede, enquanto o preguiçoso (*?, +?, ??, {n,m}?) usa o mínimo. Com exemplos executáveis.
Um quantificador como *, + ou ? indica a uma expressão regular quantas vezes o padrão anterior pode se repetir. Mas quando diferentes comprimentos de texto podem satisfazer o padrão, o motor precisa decidir qual deles usar. É essa decisão que os quantificadores gulosos e preguiçosos controlam.
Por padrão, todo quantificador é guloso: ele captura o máximo de caracteres possível. Adicione um ? após o quantificador e ele se torna preguiçoso: captura o mínimo possível. Escolher o modo errado é um dos erros mais comuns em regex — o sintoma clássico é um padrão que "corresponde a mais do que deveria." Esta página explica o mecanismo por trás de ambos os modos para que você possa escolher o certo de forma deliberada.
Como o modo guloso realmente funciona: consumir e depois retroceder
Um quantificador guloso não sabe magicamente onde parar. Ele funciona em duas fases:
- Consumir o máximo.
.*primeiro engole todo o restante da string. - Retroceder. Se o padrão que segue
.*não puder mais corresponder (porque tudo já foi consumido), o motor devolve caracteres um de cada vez, tentando novamente após cada um, até que todo o padrão se encaixe.
Portanto, guloso significa "pegar tudo, e depois reluctantemente devolver o mínimo necessário para que o restante do padrão tenha sucesso." Compreender a etapa de retrocesso é a chave para prever o comportamento de padrões gulosos.
* guloso em ação
Aqui .* corresponde a qualquer caractere zero ou mais vezes. Como não há nada obrigatório após ele, nenhum retrocesso é necessário e ele mantém tudo até o fim da linha, produzindo "ABCD*E".
+ guloso em ação
C+ corresponde a "C" uma ou mais vezes e, de forma gulosa, captura os três, então a correspondência é "ABCCC".
Como o modo preguiçoso funciona: consumir o mínimo e depois expandir
Um quantificador preguiçoso inverte a estratégia:
- Consumir o mínimo.
.*?começa correspondendo a nada. - Expandir. Somente se o restante do padrão não conseguir corresponder é que o motor deixa o quantificador preguiçoso capturar um caractere a mais, e então tenta novamente — repetindo até que todo o padrão seja satisfeito.
Portanto, preguiçoso significa "pegar o mínimo possível e crescer somente quando forçado." Você torna qualquer quantificador preguiçoso acrescentando ?.
*? preguiçoso em ação
Este é o caso confuso. O resultado é apenas "AB". Por quê? Porque .*? tem permissão de corresponder a nada, e não há nada após ele no padrão que force mais consumo. Assim que AB corresponde, o padrão já está completo, então o quantificador preguiçoso para felizmente com zero caracteres. Um quantificador preguiçoso só se expande quando algo após ele — um delimitador, um literal ou uma âncora — exige isso.
+? preguiçoso em ação
C+? deve corresponder a pelo menos um "C" (é isso que + exige), e nada após ele pede mais, então ele para no primeiro: "ABC".
O exemplo canônico: <.*> vs <.*?>
A diferença entre guloso e preguiçoso é mais fácil de ver quando há algo após o quantificador. A correspondência de tags HTML é o caso clássico. Execute ambos os padrões na mesma string:
- Guloso
/<.*>/corresponde a"<p>Hello</p>"— a string inteira..*consume tudo, depois retrocede apenas o suficiente para deixar um>para o>final no padrão, parando no último>. - Preguiçoso
/<.*?>/corresponde apenas a"<p>"— uma única tag..*?se expande caractere por caractere e para no instante em que encontra o primeiro>.
Quando seu objetivo é "corresponder a uma tag," "corresponder a uma string entre aspas" ou "corresponder até o próximo delimitador," o modo preguiçoso é quase sempre o que você quer.
A família completa de quantificadores preguiçosos
Todo quantificador guloso tem um par preguiçoso formado pela adição de ?:
| Guloso | Preguiçoso | Significado da forma preguiçosa |
|---|---|---|
* | *? | Zero ou mais, o mínimo possível |
+ | +? | Um ou mais, o mínimo possível |
? | ?? | Zero ou um, prefere zero |
{2,5} | {2,5}? | Entre 2 e 5, prefere 2 |
{2,} | {2,}? | Pelo menos 2, prefere 2 |
Note que ?? não é um erro de digitação: o primeiro ? é o quantificador (zero ou um) e o segundo o torna preguiçoso, portanto ele prefere não corresponder a nada quando tem escolha.
Quando usar quantificadores preguiçosos?
Uma regra prática:
Use um quantificador preguiçoso quando quiser corresponder até a primeira ocorrência de um delimitador, e o guloso quando quiser tudo até o último.
Situações comuns em que o modo preguiçoso é a escolha certa:
- Extrair uma única tag HTML/XML:
/<.*?>/. - Capturar o conteúdo de um par de aspas ou colchetes:
/".*?"/,/\(.*?\)/. - Capturar texto até o próximo separador sem avançar para o registro seguinte.
Dois avisos importantes:
- Um delimitador costuma ser mais claro do que a preguiça. Em vez de
/".*?"/você pode escrever/"[^"]*"/com uma classe de caracteres negada. Isso evita o retrocesso totalmente e geralmente é mais rápido e previsível. - O modo preguiçoso precisa de algo para parar. Como o exemplo
AB.*?mostrou, um quantificador preguiçoso no final de um padrão (sem nada que o force adiante) colapsa ao mínimo e corresponde a quase nada. Combine-o com um literal seguinte, uma âncora ou um grupo de captura.
Resumo
- Os quantificadores são gulosos por padrão — eles tomam o máximo e depois retrocedem para que o restante do padrão se encaixe.
- Acrescente
?para tornar um quantificador preguiçoso — ele toma o mínimo e só expande quando forçado. - Um quantificador preguiçoso sem nada após ele corresponde ao mínimo que pode legalmente (muitas vezes nada), então sempre forneça um delimitador ou âncora para que ele pare.
- A família completa de preguiçosos é
*?,+?,??e{n,m}?. - Use o modo preguiçoso quando quiser "até o primeiro" delimitador; caso contrário, uma classe de caracteres negada costuma ser a escolha mais limpa e rápida.