Noções básicas de expressões regulares
Uma expressão regular (regex) é um padrão que descreve um texto. Este guia aborda os blocos básicos que você vai usar com mais frequência e as armadilhas que causam correspondências lentas ou inesperadas.
Literais e classes de caracteres
A maioria dos caracteres corresponde a si mesma: o padrão cat encontra o texto "cat". Alguns caracteres têm significado especial, como . * + ? ( ) [ ] { } ^ $ | \. Para buscar um deles literalmente, escape-o com uma barra invertida, por exemplo \. para um ponto final.
Uma classe de caracteres corresponde a um caractere de um conjunto. [abc] corresponde a a, b ou c; [a-z] corresponde a uma letra ASCII minúscula; [^0-9] corresponde a qualquer coisa que não seja um dígito. Os atalhos comuns são \d (dígito), \w (letra, dígito ou sublinhado), \s (espaço em branco) e seus opostos \D, \W e \S. O ponto . corresponde a qualquer caractere exceto quebra de linha.
Em JavaScript, \w e \d abrangem apenas caracteres ASCII. Para encontrar letras de qualquer idioma, use uma propriedade Unicode como \p{L} com a flag u.
Quantificadores e âncoras
Os quantificadores indicam quantas vezes o item anterior pode se repetir:
| Sintaxe | Significado | Exemplo |
|---|---|---|
* |
0 ou mais | ab* corresponde a a, ab, abbb |
+ |
1 ou mais | \d+ corresponde a 7 ou 2026 |
? |
0 ou 1 | colou?r corresponde a color e colour |
{n,m} |
Entre n e m | \d{2,4} corresponde a 2 a 4 dígitos |
As âncoras correspondem a uma posição, e não a um caractere. ^ é o início e $ o fim da entrada (ou de cada linha com a flag m). \b é um limite de palavra, então \bcat\b encontra "cat", mas não "concatenate". Ao validar um valor inteiro, ancore as duas pontas: ^\d{5}$ aceita exatamente cinco dígitos e nada mais.
Grupos e capturas
Os parênteses agrupam parte de um padrão para que um quantificador ou uma alternância se aplique a ela: (ab)+ repete "ab", e (jpg|png) corresponde a qualquer uma das duas palavras. Um grupo normal também captura o texto correspondente, que você pode reutilizar em uma substituição como $1, $2 e assim por diante.
Grupos nomeados como (?<year>\d{4}) deixam os padrões mais fáceis de ler e podem ser referenciados como $<year>. Se você precisa apenas agrupar, um grupo sem captura (?:...) evita criar uma captura que não será usada. O Testador de RegEx do LeedyBox lista cada correspondência com seus grupos de captura e pré-visualiza as substituições.
Flags
As flags mudam o comportamento do padrão inteiro. As flags comuns do JavaScript são:
g(global): encontra todas as correspondências em vez de só a primeira.i(ignore case): trata maiúsculas e minúsculas como iguais.m(multiline):^e$correspondem a cada quebra de linha.s(dotAll):.também corresponde a quebras de linha.u(unicode): ativa a correspondência com reconhecimento de Unicode e as classes\p{...}.
O JavaScript também tem y (sticky) e d (índices das correspondências), que o testador também aceita.
Guloso vs preguiçoso e backtracking catastrófico
Por padrão, os quantificadores são gulosos: correspondem ao máximo possível e depois devolvem caracteres se o resto do padrão falhar. No texto <b>bold</b>, o padrão <.+> corresponde à string inteira. Acrescentar ? torna o quantificador preguiçoso, então <.+?> corresponde apenas a <b>. Uma classe negada como <[^>]+> costuma ser mais clara e mais rápida.
A maioria dos mecanismos de regex, incluindo o do JavaScript, usa backtracking. Quantificadores aninhados como (a+)+$ ou alternativas sobrepostas podem fazer o mecanismo testar um número enorme de combinações quando uma correspondência falha, o que pode travar uma página ou um servidor. Isso é chamado de backtracking catastrófico e, com entradas não confiáveis, pode ser usado em ataques de negação de serviço (ReDoS). Evite aninhar quantificadores sobre os mesmos caracteres, prefira classes específicas a .* e teste os padrões com entradas longas que não correspondem.
As variantes de regex são diferentes
Não existe um padrão único de regex. JavaScript, Python, Java, .NET, PCRE (usado pelo PHP), Go e os bancos de dados aceitam sintaxes ligeiramente diferentes. Lookbehind, quantificadores possessivos, sintaxe de grupos nomeados, classes Unicode e sintaxe de substituição variam. O mecanismo RE2 do Go, por exemplo, não suporta lookaround nem referências anteriores.
O Testador de RegEx do LeedyBox usa o mecanismo JavaScript do seu navegador. Um padrão que funciona nele pode precisar de ajustes em outra linguagem, então teste-o de novo onde ele vai ser executado.
Perguntas frequentes
Por que meu padrão encontra só a primeira ocorrência?
Sem a flag g, o JavaScript para depois da primeira correspondência. Ative a g para encontrar todas as correspondências.
Uma regex consegue validar endereços de e-mail?
Uma regex pode verificar se um valor parece plausível, mas não consegue confirmar que um endereço existe. Enviar um e-mail de confirmação é a forma usual de verificá-lo.
Por que ^ corresponde só uma vez em um texto com várias linhas?
Por padrão, ^ e $ se referem à entrada inteira. Ative a flag m para que correspondam ao início e ao fim de cada linha.