Expressões regulares são uma das ferramentas mais poderosas e odiadas na programação – poderosas porque condensam lógica complexa de correspondência de strings em alguns caracteres, odiadas porque esses caracteres são notoriamente ilegíveis e propensos a erros. Dominar regex compensa em todas as linguagens e em quase todas as funções técnicas: pesquisar e substituir em editores, validação de formulários, análise de log, extração de dados, regras de roteamento e manipulação de texto de linha de comando com ferramentas como grep e sed. As seções abaixo cobrem a sintaxe central que todo desenvolvedor deve conhecer, os padrões comuns que aparecem no trabalho real e a disciplina de teste que separa o regex funcional do tipo assustador.

A sintaxe central que todo desenvolvedor deve saber

A sintaxe Regex parece intimidante, mas os elementos principais são finitos e vale a pena memorizar. As classes de caracteres são a base: `\d` corresponde a qualquer dígito, `\w` corresponde a qualquer caractere de palavra (letras, dígitos, sublinhado), `\s` corresponde a qualquer espaço em branco e suas versões maiúsculas (`\D`, `\W`, `\S`) correspondem ao inverso. Colchetes definem classes de caracteres personalizadas: `[abc]` corresponde a qualquer um desses três caracteres, `[a-z]` corresponde a qualquer letra minúscula, `[^0-9]` corresponde a qualquer coisa, exceto dígitos. Os quantificadores especificam quantas vezes um padrão deve corresponder: `*` é zero ou mais, `+` é um ou mais, `?` é zero ou um (opcional), `{3}` é exatamente 3, `{3,5}` é de 3 a 5, `{3,}` é 3 ou mais. Os quantificadores são gananciosos por padrão, combinando o máximo possível; adicionar `?` os torna preguiçosos (`*?`, `+?`). As âncoras correspondem a posições em vez de caracteres: `^` é o início da string (ou linha com o sinalizador `m`), `$` é o fim da string, `\b` é um limite de palavra. O agrupamento usa parênteses `(...)` para agrupar operadores e capturar o texto correspondente para referência posterior. Esses blocos de construção básicos cobrem 90% das necessidades práticas de regex, e a maior parte do mistério da regex se dissolve quando você internaliza esse vocabulário. Todo o resto são variações desses temas.

Padrões comuns que aparecem no trabalho real

Vários padrões aparecem com tanta frequência nos projetos que vale a pena memorizá-los como modelos. Endereço de e-mail (validação livre): `/^[\w.+-]+@[\w-]+\.[\w.-]+$/` — bom o suficiente para filtragem de formulários, embora o regex de e-mail formalmente correto seja impossivelmente longo para escrita humana. Correspondência de URL: `/https?:\/\/[^\s]+/g` — ótimo para extrair URLs de texto, embora corresponda à pontuação final que você deseja cortar. Números de telefone dos EUA: `/\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}/` — trata parênteses, travessões e espaços como separadores opcionais. Endereços IP (IPv4): `/\b(?:\d{1,3}\.){3}\d{1,3}\b/` — simples, mas não rejeita 999.999.999.999 (que requer uma lógica de restrição de valor feia). Datas ISO: `/\d{4}-\d{2}-\d{2}/` com grupos nomeados opcionais `(?\d{4})-(?\d{2})-(?\d{2})` para extração. Cores hexadecimais: `/#[0-9a-f]{3,8}\b/i`. Número do cartão de crédito (avulso): `/\b\d{13,19}\b/` — apenas para verificação de formato, não de validade. UUID: `/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i`. A biblioteca de padrões na maioria dos sites regex expande esse conjunto substancialmente, e copiar um padrão testado em batalha é quase sempre melhor do que escrever o seu próprio para formatos comuns. Nomeie seus grupos de captura quando precisar extrair dados — a sintaxe `(?...)` torna o código resultante muito mais legível do que `match[1]` / `match[2]`.

Disciplina de teste: como escrever Regex que realmente funcione

A diferença entre regex que funciona de maneira confiável e regex que interrompe a produção é a disciplina de teste. Quatro práticas distinguem consistentemente os dois. Primeiro, sempre teste em casos positivos (entradas que devem corresponder) E casos negativos (entradas que não devem corresponder). É fácil criar um padrão que corresponda a tudo o que você deseja, apenas para descobrir que ele também corresponde a entradas que você não deseja. Um conjunto de testes com 10 positivos e 10 negativos detecta a maioria dos problemas. Em segundo lugar, teste especificamente em casos extremos: string vazia, caractere único, strings muito longas, caracteres Unicode, strings com apenas espaços em branco, strings com novas linhas, strings com caracteres regex especiais. Os padrões Regex têm um comportamento surpreendente em torno dessas bordas, e a entrada de produção acabará por incluir todos eles. Terceiro, cuidado com o retrocesso catastrófico. Um padrão como `(a+)+b` comparado a `aaaaaaaaaaaaaaaaX` pode levar um tempo exponencial porque o mecanismo tenta todos os agrupamentos possíveis de `a`s. Teste qualquer padrão complexo contra entradas aparentemente maliciosas (longas sequências de caracteres repetidos) e observe o tempo de execução. Os ataques ReDoS (Regular Expression Denial of Service) exploram exatamente essa vulnerabilidade em padrões mal elaborados usados ​​na validação de entrada. Quarto, use um testador de regex real (este, ou um plug-in de editor) durante o desenvolvimento, em vez de tentativa e erro no código de produção - o feedback visual de assistir aos destaques das partidas ao vivo enquanto você digita produz padrões de trabalho 5 a 10 vezes mais rápido do que depurar testes com falha após o fato.