Expressões Regulares: Um Guia para Iniciantes
· 12 min de leitura
📑 Índice
- O Que São Expressões Regulares?
- Blocos de Construção Básicos
- Quantificadores Explicados
- Classes de Caracteres e Atalhos
- Âncoras e Limites
- Grupos e Captura
- Exemplos Práticos
- Técnicas Avançadas
- Armadilhas Comuns e Como Evitá-las
- Testando e Depurando Regex
- Considerações de Desempenho
- Perguntas Frequentes
Expressões regulares (regex) são uma das ferramentas mais poderosas no arsenal de um desenvolvedor. Elas podem parecer intimidadoras no início, mas uma vez que você entende o básico, elas se tornam indispensáveis para processamento de texto, validação e extração de dados.
Seja validando entrada de usuário, analisando arquivos de log ou transformando dados, regex fornece uma maneira concisa e flexível de trabalhar com padrões de texto. Este guia vai levá-lo de iniciante completo a usuário confiante de regex.
O Que São Expressões Regulares?
Uma expressão regular é uma sequência de caracteres que define um padrão de busca. Pense nela como uma mini-linguagem para descrever padrões de texto—em vez de buscar strings exatas, você pode buscar padrões como "qualquer endereço de email" ou "qualquer número de telefone."
Expressões regulares são usadas em praticamente todas as linguagens de programação e editores de texto. Elas são suportadas em JavaScript, Python, Java, PHP, Ruby, Go e inúmeras outras linguagens. Até ferramentas de linha de comando como grep, sed e awk dependem fortemente de regex.
A beleza do regex é que uma vez que você aprende a sintaxe, pode aplicá-la em diferentes ferramentas e linguagens. Embora existam pequenas diferenças entre "sabores" de regex (PCRE, JavaScript, Python, etc.), os conceitos centrais permanecem os mesmos.
Dica profissional: Comece com padrões simples e gradualmente construa complexidade. Não tente escrever um regex perfeito na primeira tentativa—itere e refine conforme você testa.
Blocos de Construção Básicos
Todo padrão regex é construído a partir de componentes fundamentais. Entender esses blocos de construção é essencial antes de avançar para padrões mais complexos.
Caracteres Literais
O regex mais simples é apenas texto simples. O padrão cat corresponde ao texto exato "cat" em qualquer lugar da sua string. A maioria dos caracteres alfanuméricos correspondem a si mesmos literalmente.
No entanto, alguns caracteres têm significados especiais em regex e precisam ser escapados com uma barra invertida: . ^ $ * + ? { } [ ] \ | ( )
Para corresponder a um ponto literal, você escreveria \. em vez de apenas .
O Metacaractere Ponto
O ponto (.) é um curinga que corresponde a qualquer caractere único exceto nova linha. O padrão c.t corresponde a "cat", "cot", "cut", "c9t" e até "c@t".
Isso torna o ponto incrivelmente poderoso, mas também potencialmente perigoso se usado descuidadamente. Vamos cobrir como torná-lo mais específico mais tarde.
Classes de Caracteres
Colchetes criam uma classe de caracteres, correspondendo a qualquer caractere único dentro dos colchetes:
[aeiou]corresponde a qualquer vogal[0-9]corresponde a qualquer dígito[a-zA-Z]corresponde a qualquer letra (maiúscula ou minúscula)[a-z0-9]corresponde a qualquer letra minúscula ou dígito
Você também pode negar uma classe de caracteres com um acento circunflexo: [^0-9] corresponde a qualquer caractere que NÃO seja um dígito.
Quantificadores Explicados
Quantificadores especificam quantas vezes um padrão deve corresponder. Eles são colocados após o elemento que você deseja repetir.
| Quantificador | Significado | Exemplo |
|---|---|---|
* |
0 ou mais vezes | ab*c corresponde a "ac", "abc", "abbc" |
+ |
1 ou mais vezes | ab+c corresponde a "abc", "abbc" mas não "ac" |
? |
0 ou 1 vez (opcional) | colou?r corresponde a "color" e "colour" |
{n} |
Exatamente n vezes | \d{3} corresponde a exatamente 3 dígitos |
{n,} |
n ou mais vezes | \d{2,} corresponde a 2 ou mais dígitos |
{n,m} |
Entre n e m vezes | \d{2,4} corresponde a 2, 3 ou 4 dígitos |
Correspondência Gananciosa vs. Preguiçosa
Por padrão, quantificadores são gananciosos—eles correspondem ao máximo de texto possível. O padrão .* vai consumir tudo que puder.
Considere corresponder tags HTML: <.+> aplicado a <b>bold</b> vai corresponder à string inteira, não apenas <b>.
Para tornar quantificadores preguiçosos (corresponder o mínimo possível), adicione um ponto de interrogação: <.+?> agora vai corresponder a <b> e </b> separadamente.
Dica rápida: Na dúvida, use quantificadores preguiçosos. Eles são mais previsíveis e menos propensos a causar correspondências inesperadas.
Classes de Caracteres e Atalhos
Escrever [0-9] repetidamente fica tedioso. Regex fornece classes de caracteres abreviadas para padrões comuns.
| Abreviação | Equivalente | Descrição |
|---|---|---|
\d |
[0-9] |
Qualquer dígito |
\D |
[^0-9] |
Qualquer não-dígito |
\w |
[a-zA-Z0-9_] |
Qualquer caractere de palavra |
\W |
[^a-zA-Z0-9_] |
Qualquer caractere não-palavra |
\s |
[ \t\r\n\f] |
Qualquer caractere de espaço em branco |
\S |
[^ \t\r\n\f] |
Qualquer caractere não-espaço em branco |
Note o padrão: versões maiúsculas são negações de suas contrapartes minúsculas. Isso torna o regex mais legível e conciso.
Exemplos Práticos com Atalhos
\d{3}-\d{4}corresponde a números de telefone como "555-1234"\w+@\w+\.\w+corresponde a endereços de email simples\s+corresponde a um ou mais caracteres de espaço em branco\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}corresponde a endereços IP (embora não perfeitamente)
Âncoras e Limites
Âncoras não correspondem a caracteres—elas correspondem a posições no texto. Elas são essenciais para correspondência de padrões precisa.
Âncoras de Linha
^corresponde ao início de uma linha$corresponde ao final de uma linha
O padrão ^Hello só corresponde a "Hello" no início de uma linha. Similarmente, world$ só corresponde a "world" no final de uma linha.
Para corresponder a uma linha inteira exatamente, use ambos: ^Hello world$ corresponde apenas a linhas contendo exatamente "Hello world" sem nada antes ou depois.
Limites de Palavra
A âncora \b corresponde a limites de palavra—a posição entre um caractere de palavra (\w) e um caractere não-palavra.
Isso é incrivelmente útil para corresponder palavras inteiras. O padrão \bcat\b corresponde a "cat" mas não a "category" ou "scat".
Sem limites de palavra, cat corresponderia a todas as três. Limites de palavra tornam seus padrões mais precisos sem adicionar complexidade.
Dica profissional: Sempre use limites de palavra ao buscar palavras inteiras. Isso previne correspondências falsas e torna seu regex mais confiável.
Grupos e Captura
Parênteses servem a dois propósitos em regex: agrupamento e captura. Eles são um dos recursos mais poderosos uma vez que você entende como funcionam.
Agrupamento para Quantificadores
Parênteses permitem que você aplique quantificadores a múltiplos caracteres. O padrão (ha)+ corresponde a "ha", "haha", "hahaha", etc.
Sem parênteses, ha+ corresponderia a "ha", "haa", "haaa"—o quantificador só se aplica ao caractere precedente.
Grupos de Captura
Grupos também capturam o texto correspondido para uso posterior. Considere este padrão de número de telefone: (\d{3})-(\d{3})-(\d{4})
Isso cria três grupos de captura: código de área, prefixo e número de linha. Na maioria das linguagens, você pode acessar essas capturas:
- JavaScript:
match[1],match[2],match[3] - Python:
match.group(1),match.group(2),match.group(3) - Em substituições:
$1,$2,$3ou\1,\2,\3
Grupos Não-Capturantes
Às vezes você quer agrupamento sem captura. Use (?:...) para grupos não-capturantes: (?:https?://)?www\.example\.com
Isso agrupa o protocolo mas não cria um grupo de captura, o que pode melhorar o desempenho e simplificar seu código.
Grupos de Captura Nomeados
Em vez de grupos numerados, você pode nomeá-los para clareza: (?<area>\d{3})-(?<prefix>\d{3})-(?<line>\d{4})
Acesse grupos nomeados com match.group('area') em Python ou match.groups.area em JavaScript. Isso torna seu código autodocumentado.
Exemplos Práticos
Vamos aplicar o que aprendemos a cenários do mundo real. Esses padrões são pontos de partida—você frequentemente precisará ajustá-los para seus requisitos específicos.
Validação de Email
Um padrão de email simples: [\w.+-]+@[\w.-]+\.[a-zA-Z]{2,}
Isso corresponde à maioria dos formatos de email comuns, mas não é compatível com RFC. Para uso em produção, considere usar uma biblioteca dedicada de validação de email—regex de email pode ficar extremamente complexo.
Correspondência de URL
Corresponder URLs HTTP e HTTPS: https?://[\w.-]+(?:\.[\w.-]+)+(?:/[\w./?&=%-]*)?
Isso lida com domínios, caminhos e strings de consulta. O s? torna o 's' em 'https' opcional.
Números de Telefone
Números de telefone dos EUA com formatação flexível: \(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}
Isso corresponde a formatos como:
- (555) 123-4567
- 555-123-4567
- 555.123.4567
- 5551234567
Formatos de Data
Formato de data ISO (AAAA-MM-DD): \d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])
Isso garante que os meses sejam 01-12 e os dias sejam 01-31. É mais preciso que \d{4}-\d{2}-\d{2} que aceitaria datas inválidas como 2024-99-99.
Endereços IP
Endereços IPv4: \b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b
Isso valida que cada octeto está entre 0-255, prevenindo correspondências como 999.999.999.999.
Números de Cartão de Crédito
Corresponder números de cartão de crédito com espaços ou traços opcionais: \d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}
Lembre-se de validar o checksum separadamente usando o algoritmo de Luhn—regex sozinho não pode verificar se um número de cartão é válido.
Nota de segurança: Nunca registre ou armazene números de cartão de crédito em texto simples. Use esses padrões apenas para validação inicial de formato, então imediatamente tokenize dados sensíveis.
Extraindo Dados de Logs
Analisar entradas de log do Apache: