Expressões Regulares: Um Guia Prático com Exemplos

· 12 min de leitura

Expressões regulares (regex) são uma das ferramentas mais poderosas no kit de ferramentas de um desenvolvedor, mas frequentemente são mal compreendidas ou totalmente evitadas. Seja validando entrada de usuário, analisando arquivos de log ou transformando dados de texto, regex fornece uma maneira concisa e eficiente de corresponder padrões em strings.

Este guia abrangente levará você do básico de regex a técnicas avançadas, com exemplos práticos que você pode usar imediatamente em seus projetos. Ao final, você entenderá não apenas como regex funciona, mas quando e por que usá-lo.

Índice

O Que É Regex e Por Que Você Deveria Se Importar?

Uma expressão regular é uma sequência de caracteres que define um padrão de busca. Pense nisso como uma mini-linguagem especificamente projetada para correspondência de padrões em texto. Em vez de buscar strings exatas, regex permite que você descreva padrões como "qualquer endereço de email" ou "todos os números de telefone neste formato."

Regex é suportado em praticamente todas as linguagens de programação e muitas ferramentas de linha de comando. Uma vez que você aprende a sintaxe, pode aplicá-la em qualquer lugar—de JavaScript e Python a grep e sed.

Casos de uso comuns incluem:

Dica profissional: Embora regex seja poderoso, nem sempre é a ferramenta certa. Para tarefas complexas de análise como HTML ou JSON, use analisadores dedicados. Regex funciona melhor para padrões bem definidos e relativamente simples.

Básico de Regex: Blocos de Construção

Todo padrão regex é construído a partir de blocos de construção fundamentais. Entender esses elementos centrais é essencial antes de avançar para padrões mais complexos.

Caracteres Literais

O regex mais simples é apenas texto literal. O padrão cat corresponde à string exata "cat" no seu texto. A maioria dos caracteres alfanuméricos correspondem a si mesmos diretamente.

Metacaracteres

Certos caracteres têm significados especiais em regex. Estes são chamados metacaracteres e incluem: . ^ $ * + ? { } [ ] \ | ( )

Para corresponder esses caracteres literalmente, você precisa escapá-los com uma barra invertida. Por exemplo, \. corresponde a um ponto literal.

O Curinga Ponto

O ponto . é o curinga mais básico—ele corresponde a qualquer caractere único exceto nova linha. O padrão a.c corresponde a "abc", "a1c", "a-c", mas não "ac" (nenhum caractere entre) ou "a\nc" (nova linha).

Padrão Corresponde Exemplo
. Qualquer caractere (exceto nova linha) a.c corresponde abc, a1c, a-c
\d Qualquer dígito [0-9] \d{3} corresponde 123, 456
\w Caractere de palavra [a-zA-Z0-9_] \w+ corresponde hello, user_1
\s Espaço em branco (espaço, tab, nova linha) \s+ corresponde espaços, tabs
\D Não-dígito \D+ corresponde abc, xyz
\W Caractere não-palavra \W+ corresponde !@#, espaços
\S Não-espaço em branco \S+ corresponde qualquer texto visível

Note que as versões maiúsculas (\D, \W, \S) são o inverso de suas contrapartes minúsculas. Este é um padrão comum na sintaxe regex.

Quantificadores: Controlando Repetição

Quantificadores especificam quantas vezes um padrão deve se repetir. Eles são colocados após o elemento que você quer repetir e são fundamentais para criar padrões flexíveis.

Quantificadores Básicos

Quantificador Significado Exemplo
* 0 ou mais vezes ab*c corresponde ac, abc, abbc, abbbc
+ 1 ou mais vezes ab+c corresponde abc, abbc (não ac)
? 0 ou 1 vez (opcional) colou?r corresponde color, colour
{n} Exatamente n vezes \d{4} corresponde 2026, 1999
{n,} n ou mais vezes \d{3,} corresponde 123, 1234, 12345
{n,m} Entre n e m vezes \d{2,4} corresponde 12, 123, 1234

Correspondência Gananciosa vs. Preguiçosa

Por padrão, quantificadores são gananciosos—eles correspondem o máximo de texto possível. Isso pode levar a resultados inesperados ao corresponder padrões como tags HTML.

// Correspondência gananciosa
const text = "<div>Hello</div><div>World</div>";
const greedy = /<.*>/;
// Corresponde: "<div>Hello</div><div>World</div>" (string inteira!)

// Correspondência preguiçosa
const lazy = /<.*?>/;
// Corresponde: "<div>" (para no primeiro colchete de fechamento)

Adicionar ? após um quantificador o torna preguiçoso (não-ganancioso). Quantificadores preguiçosos correspondem o mínimo de texto possível enquanto ainda satisfazem o padrão.

Dica rápida: Ao corresponder conteúdo entre delimitadores (aspas, colchetes, tags), quantificadores preguiçosos são geralmente o que você quer. Use .*? em vez de .* para evitar corresponder demais.

Classes de Caracteres e Atalhos

Classes de caracteres permitem que você corresponda qualquer caractere de um conjunto específico. Elas são definidas usando colchetes e são incrivelmente úteis para criar padrões flexíveis.

Classes de Caracteres Básicas

// Corresponder qualquer vogal
/[aeiou]/

// Corresponder qualquer dígito
/[0-9]/

// Corresponder qualquer letra minúscula
/[a-z]/

// Corresponder qualquer letra (sem distinção de maiúsculas)
/[a-zA-Z]/

// Corresponder caracteres alfanuméricos
/[a-zA-Z0-9]/

Classes de Caracteres Negadas

Use ^ no início de uma classe de caracteres para negá-la—correspondendo qualquer caractere exceto aqueles listados.

// Corresponder qualquer não-dígito
/[^0-9]/

// Corresponder qualquer não-vogal
/[^aeiou]/

// Corresponder qualquer caractere exceto espaço ou tab
/[^ \t]/

Caracteres Especiais em Classes

A maioria dos metacaracteres perde seu significado especial dentro de classes de caracteres. Você pode incluir ., *, + e ? sem escapá-los. No entanto, você ainda precisa escapar ], \, ^ e - em certas posições.

// Corresponder um ponto ou vírgula
/[.,]/

// Corresponder um hífen (escapar ou colocar no início/fim)
/[-a-z]/ ou /[a-z-]/

// Corresponder um colchete de fechamento (deve escapar)
/[\]]/

Grupos e Capturas

Grupos servem dois propósitos principais: eles permitem que você aplique quantificadores a múltiplos caracteres, e capturam texto correspondido para uso posterior.

Grupos de Captura

Parênteses criam grupos de captura que lembram o texto correspondido. Isso é essencial para extrair dados de strings.

// Extrair componentes de data
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2026-03-29".match(datePattern);

// match[0]: "2026-03-29" (correspondência completa)
// match[1]: "2026" (primeiro grupo)
// match[2]: "03" (segundo grupo)
// match[3]: "29" (terceiro grupo)

Grupos de Captura Nomeados

Grupos nomeados tornam seu regex mais legível e seu código mais sustentável. Em vez de se referir a grupos por número, você dá a eles nomes descritivos.

// Sintaxe de grupos nomeados: (?<name>pattern)
const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = "2026-03-29".match(datePattern);

// Acessar por nome
console.log(match.groups.year);  // "2026"
console.log(match.groups.month); // "03"
console.log(match.groups.day);   // "29"

Grupos Não-Capturadores

Às vezes você precisa de agrupamento para quantificadores ou alternância mas não quer capturar o texto. Grupos não-capturadores usam a sintaxe (?:...).

// Capturar o protocolo sem criar um grupo
/(?:https?|ftp):\/\/([a-z.]+)/

// Isso cria apenas um grupo de captura (o domínio)
// O grupo de protocolo (?:https?|ftp) não captura

Grupos não-capturadores são mais rápidos e usam menos memória que grupos de captura. Use-os quando você não precisar do texto capturado.

Referências Retroativas

Referências retroativas permitem que você corresponda o mesmo texto que foi capturado por um grupo anterior. Isso é útil para encontrar palavras repetidas ou corresponder delimitadores pareados.

// Encontrar palavras repetidas
/\b(\w+)\s+\1\b/
// Corresponde "the the" ou "hello hello"

// Corresponder aspas pareadas
/(['"])(.*?)\1/
// Corresponde "hello" ou 'world' mas não "mixed'

Alternância

O operador pipe | cria alternância—correspondendo um padrão ou outro. É como um OU lógico.

// Corresponder cat, dog ou bird
/cat|dog|bird/

// Corresponder extensões de arquivo comuns
/\.(jpg|jpeg|png|gif|webp)$/i

// Corresponder Mr., Mrs., Ms. ou Dr.
/(?:Mr|Mrs|Ms|Dr)\./

Âncoras e Limites

Âncoras não correspondem caracteres—elas correspondem posições na string. Elas são essenciais para garantir que padrões apareçam em locais específicos.

Âncoras de String

// Deve começar com "Hello"
/^Hello/

// Deve terminar com "world"
/world$/

// String inteira deve ser exatamente 5 dígitos
/^\d{5}$/

Limites de Palavra

A âncora \b corresponde limites de palavra—posições entre caracteres de palavra e não-palavra. Isso é crucial para corresponder palavras inteiras.

// Corresponder "cat" como uma palavra inteira
/\bcat\b/
// Corresponde: "cat", "the cat sat"
// Não corresponde: "category", "scat"

// Corresponder palavras começando com "pre"
/\bpre\w+/
// Corresponde: "preview", "prepare", "prefix"

O inverso \B corresponde não-limites de palavra—posições onde ambos os lados são caracteres de palavra ou ambos são caracteres não-palavra.

Dica profissional: Sempre use limites de palavra ao buscar palavras inteiras. Sem eles, buscar por "cat" também corresponderá "category" e "concatenate". O padrão \bcat\b garante que você corresponda apenas a palavra completa.

Padrões Comuns para Uso no Mundo Real

Aqui estão padrões regex testados em batalha para tarefas comuns de validação e extração. Esses padrões equilibram simplicidade com precisão prática.

Tipo de Padrão Regex Notas
Email (simples) ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$ Bom para validação básica
Email (compatível com RFC) ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ Mais rigoroso, amplamente aceito
URL ^https?:\/\/[\w.-]+(?:\.[a-zA-Z]{2,})(?:\/\S*)?$ URLs HTTP/HTTPS básicas
Endereço IPv4 ^(?:\d{1,3}\.){3}\d{1,3}$ Apenas formato, não valida intervalos
IPv4 (rigoroso) ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ Valida intervalo 0-255
Data (AAAA-MM-DD) ^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$ Formato ISO 8601
Hora (24 horas) ^(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$ HH:MM ou HH:MM:SS
Telefone (EUA) ^\+?1?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$ Formatação flexível
Cor Hex ^#(?:[0-9a-fA-F]{3}){1,2}$ Códigos hex de 3 ou 6 dígitos
Cartão de Crédito ^\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}$ Apenas formato, use Luhn para validação
Nome de usuário ^[a-zA-Z0-9_-]{3,16}$ 3-16 caracteres, alfanumérico mais _ e -
Slug ^[a-z0-9]+(?:-[a-z0-9]+)*$ Minúsculas amigáveis para URL com hífens

Validação de Senha

Validação de senha requer verificar múltiplas condições simultaneamente. Asserções lookahead tornam isso possível sem lógica complexa.

// Senha forte: 8+ caracteres, maiúscula, minúscula, dígito, caractere especial
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/

// Detalhando:
// (?=.*[a-z])     - pelo menos uma letra minúscula
// (?=.*[A-Z])     -