Skip to content

Guide

Folha de cola de Regex: padrões comuns que todo desenvolvedor precisa

Vinte e cinco padrões que você realmente usará, a distinção guloso/preguiçoso que causa metade dos bugs de regex e onde o regex do JavaScript difere do PCRE.

By Published

Um regex funcional não é uma linha que você memoriza; é uma linha mais as suposições sobre sua entrada e seu sabor. Esta folha de cola combina cada padrão com o que ele realmente corresponde, os casos extremos que perde e em quais motores de regex funciona. Coloque qualquer um deles em nosso testador de regex ao vivo para ver correspondências e capturas interativamente.

Notação usada abaixo

Os padrões são mostrados sem os delimitadores /.../ circundantes, exceto onde as flags importam. Assuma que ^ e $ estão ancorados a um único valor (todo o campo), não a múltiplas linhas. Quando um padrão usa recursos que não são universais, a nota de sabor especifica em quais motores funciona. Onde há tanto uma forma permissiva quanto estrita, ambas são fornecidas.

Identificadores e nomes

E-mail — permissivo

^[^\s@]+@[^\s@]+\.[^\s@]+$

Três classes de caracteres separadas por @ e ., nenhuma das quais contém espaço em branco ou outro@. Aceita quase todo e-mail do mundo real e rejeita os erros de digitação mais óbvios. Não valida contra RFC 5322 — partes locais entre aspas e domínios IP-literal passam ou são rejeitados dependendo do canto.

E-mail — especificação de formulário HTML5

^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

O padrão que o WHATWG especifica para HTML input type=“email“. Mais rígido que a forma permissiva, mas ainda não reivindica cobertura completa de RFC 5322 — a especificação diz explicitamente “deliberadamente não conforme.” Use isso quando quiser corresponder ao comportamento do navegador.

URL — somente HTTPS

^https://[^\s/$.?#].[^\s]*$

URL HTTPS permissiva. Rejeita lixo óbvio, mas aceita qualquer coisa após o host que seja não-espaço em branco. Para validação real, delegue a new URL() na linguagem host; regex é para filtrar entradas, não para analisá-las.

Slug (identificador seguro para URL)

^[a-z0-9]+(?:-[a-z0-9]+)*$

Letras minúsculas e dígitos com hifens únicos entre grupos. Sem hifens no início ou no fim, sem hifens duplos. Esta é a forma de slug que todo CMS usa.

Nome de usuário — alfanumérico e sublinhado, 3–20 chars

^[A-Za-z0-9_]{3,20}$

UUID (qualquer versão)

^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$

UUID v4 (estrito)

^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$

Impõe o 4 na posição 13 e os bits de variante na posição 17 (um de 8, 9, a, b). Use isso quando se importar com a versão, não apenas a forma.

Números, dinheiro, códigos

Inteiro (com sinal)

^-?\d+$

Número decimal (com sinal, parte fracionária opcional)

^-?\d+(?:\.\d+)?$

Valor monetário (estilo americano)

^\$?\d{1,3}(?:,\d{3})*(?:\.\d{2})?$

Sinal de dólar opcional, separadores de milhar a cada três dígitos, centavos de dois decimais opcionais. Não lida com negativos; para uso contábil, prefixe ^-? ou envolva em parênteses.

Cor hex (3, 4, 6 ou 8 dígitos)

^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$

As formas de 4 e 8 dígitos incluem um canal alfa (#RRGGBBAA) suportado pelo CSS Color Level 4 e todos os navegadores modernos.

Versão semântica (semver 2.0.0)

^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

Este é o regex canônico publicado em semver.org. Captura major, minor, patch, pré-lançamento opcional e metadados de build opcionais. Rejeita corretamente zeros à esquerda em componentes numéricos.

Datas e horas

Data ISO 8601 (AAAA-MM-DD)

^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$

Restringe o mês a 01–12 e o dia a 01–31. Não valida que o dia existe no mês dado (30 de fevereiro passa). Para validação real de data, analise com a linguagem host e verifique erros.

Timestamp ISO 8601 com fuso horário

^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$

Aceita Z para UTC ou um deslocamento numérico como +02:00. Permite segundos fracionários opcionais.

HH:MM hora em formato 24h

^(?:[01]\d|2[0-3]):[0-5]\d$

Endereços de rede

IPv4

^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$

Intervalo de octeto estritamente 0–255. Rejeita zeros à esquerda como 192.168.001.001 (que é inequívoco para humanos, mas alguns sistemas interpretam como octal, então a rejeição é defensável).

IPv6 — prático

^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$

Corresponde à forma canônica de oito grupos. Não corresponde a IPv6 com compressão :: ou com IPv4 incorporado como ::ffff:192.0.2.1. O regex completo RFC 4291 tem mais de cem caracteres; para uso em produção, delegue ao equivalente inet-pton da sua linguagem.

Endereço MAC

^(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}$

Número de porta

^(?:6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$

0–65535, estritamente delimitado.

Números de telefone

Telefone americano — permissivo

^(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$

+1 opcional, parênteses opcionais ao redor do código de área, separadores opcionais de hífen, ponto ou espaço. Aceita os formatos americanos comuns; rejeita números não americanos.

Telefone internacional (E.164)

^\+[1-9]\d{1,14}$

E.164 é a especificação ITU: + inicial, código de país começando com não-zero, comprimento total de 2–15 dígitos incluindo o código do país. Sem espaços, sem parênteses. Este é o formato que cada gateway SMS e a maioria dos CRMs esperam.

Strings e estrutura

String somente com espaço em branco

^\s*$

Remover espaço em branco inicial/final (substituir por vazio)

^\s+|\s+$

Colapsar múltiplos espaços em um (substituir por espaço único)

\s{2,}

Corresponder conteúdo entre colchetes (preguiçoso)

\[([^\]]*)\]

Captura caracteres que não são um colchete de fechamento — a classe de caracteres negada é a forma mais limpa de fazer “tudo até o próximo delimitador” de forma não gulosa.

Comportamento do quantificador

Guloso (o padrão)

*, +, ? e {n,m} correspondem ao máximo possível por padrão, depois recuam para encontrar uma correspondência para o resto do padrão. Em <b>oi</b><b>tchau</b>, o padrão <b>.*</b> corresponde à string inteira, não ao primeiro par de tags.

Preguiçoso (sufixo ?)

Adicione um ? para fazer um quantificador corresponder ao mínimo possível. <b>.*?</b> corresponde a <b>oi</b> apenas, o que é quase sempre o que você queria.

Quantificadores possessivos e grupos atômicos

Quantificadores possessivos (*+, ++) e grupos atômicos ((?>...)) recusam fazer backtracking uma vez correspondidos. Eliminam o backtracking catastrófico em entradas patológicas. PCRE, Java e Ruby os suportam; JavaScript não (use uma solução alternativa como um lookahead com uma referência anterior).

Lookahead e lookbehind

Lookarounds afirmam uma condição sem consumir caracteres. São de largura zero.

  • Lookahead positivo (?=...) — “seguido por.” \d+(?=px) corresponde a dígitos seguidos de px sem incluirpx na correspondência.
  • Lookahead negativo (?!...) — “não seguido por.” foo(?!bar) corresponde a foo não seguido de bar.
  • Lookbehind positivo (?<=...)— “precedido por.”
  • Lookbehind negativo (?<!...)— “não precedido por.”

JavaScript suporta lookahead em todas as versões, lookbehind apenas a partir do ES2018. Muitos motores mais antigos (e a versão V8 em algumas builds Node empacotadas) limitam lookbehinds a padrões de largura fixa; PCRE e o módulo regex do Python permitem largura variável.

Diferenças de sabor que vale lembrar

  • JavaScript: sem quantificadores possessivos, sem grupos atômicos, lookbehind a partir do ES2018. A flag g (global) faz String.match retornar todas as correspondências, mas String.replace se comporta de forma diferente — o canto mais bugado do regex JS.
  • PCRE (Compatível com Perl): o superconjunto de recursos. Usado por PHP, nginx, muitas ferramentas de linha de comando. Padrões recursivos, condicionais, quantificadores possessivos, grupos atômicos, capturas nomeadas — todos suportados.
  • Python: o módulo re padrão é próximo do PCRE menos alguns recursos. O módulo de terceiros regex adiciona o restante, mais lookbehinds de largura variável e grupos atômicos.
  • Go (RE2): deliberadamente de tempo linear. Sem referências anteriores, sem lookaround. Mais lento em padrões simples, imune ao backtracking catastrófico. O crate regex do Rust é da mesma família.
  • .NET: similar ao PCRE, mais alguns recursos únicos como grupos de balanceamento (que permitem realmente corresponder colchetes aninhados — de uma forma que nenhum outro sabor pode).

Uma flag que vale destacar entre os sabores: Unicode property escapes (\p{Letter}, \p{Number}, \p{Script=Greek}) correspondem por categoria de codepoint em vez de byte bruto. JavaScript precisa da flag u, PCRE precisa de (*UCP) ou do modificador /u, Python os suporta no módulo regex de terceiros. Sem eles, \w significa apenas ASCII [A-Za-z0-9_]e seu padrão de “corresponder qualquer nome” silenciosamente rejeita metade do mundo.

Os padrões que nunca deve escrever

  • Análise de HTML. Use um parser real (DOMParser no navegador, BeautifulSoup em Python, go-html em Go). Regex pode extrair um único atributo de uma forma bem conhecida, nada mais.
  • Análise de JSON. Toda linguagem tem JSON.parse. Use-o.
  • Análise de linguagem de programação. Use um combinador de parsers ou uma gramática real.
  • Qualquer coisa que precise corresponder delimitadores aninhados. Linguagens regulares clássicas não podem contar. Use um parser.

A conclusão honesta

Regex é uma ferramenta precisa com um domínio pequeno e bem compreendido: strings de forma fixa, filtragem simples de entrada, pesquisa e substituição em editores de texto. Os padrões nesta folha de cola cobrem os 80% dos casos que surgem no código cotidiano. Para os 20% que parecem regex, mas não são — estruturas aninhadas, correspondência de linguagem natural, validação semântica — opte por um parser.

E quando você escrever um regex, cole-o em nosso testador com três entradas representativas e três entradas patológicas antes de fazer o commit. O padrão que funciona no seu único caso de teste é o padrão que derruba a produção para outra pessoa.

Frequently asked questions

Por que meu regex de e-mail rejeita endereços válidos?
Porque a gramática RFC 5322 para endereços de e-mail válidos tem mais de uma página e inclui construções como partes locais entre aspas ("user name"@example.com) e domínios IP-literal (user@[192.168.0.1]). A maioria dos 'regex de e-mail' aplica um subconjunto comum minúsculo. Para validação real, envie um e-mail de confirmação — o regex só pode filtrar erros de digitação óbvios.
Os sabores de regex são realmente tão diferentes entre linguagens?
Sim. O JavaScript suporta lookahead, mas só ganhou lookbehind em 2018 (ES2018) e grupos nomeados na mesma versão. Python usa re para regex básico e regex para recursos avançados como padrões recursivos. PCRE tem mais recursos e é o mais próximo de um 'superconjunto de regex'. .NET tem suas próprias peculiaridades. Sempre teste no runtime real, não no regex101 com o sabor errado selecionado.
Quantificadores gulosos vs preguiçosos — qual quero?
Guloso (o padrão) corresponde ao máximo possível; preguiçoso (sufixo ?) corresponde ao mínimo possível. Para .* dentro de tags HTML, você quase sempre quer preguiçoso: .*? — caso contrário, <b>oi</b><b>tchau</b> corresponde a tudo desde o primeiro <b> até o último </b>. Para análise numérica onde o comprimento do campo é conhecido, guloso geralmente está bom.
Quando não devo usar regex?
Analisar HTML, JSON, YAML, linguagens de programação ou qualquer coisa com estrutura aninhada. Regex é uma ferramenta para linguagens regulares; no momento em que você precisa contar ou recursar (correspondendo colchetes aninhados, correspondendo tags abertas/fechadas), use um parser real. A resposta 'analisar HTML com regex' no Stack Overflow tornou-se um clássico de culto porque o conselho está correto.
Qual é a maneira mais segura de validar uma URL?
Passe-a para o construtor URL na linguagem real — new URL(input) do JavaScript, urllib.parse.urlparse do Python, java.net.URI do Java. Estes implementam os RFCs relevantes e lidam com casos extremos (domínios internacionais, faixas de porta, validação de esquema) que um regex não vai. Use regex apenas para filtrar plausibilidade sintática antes dessa chamada.
Por que meu regex é tão lento em certas entradas?
Backtracking catastrófico. Padrões com quantificadores aninhados ou sobrepostos — como (a+)+ ou (.*).* — podem levar tempo exponencial em certas entradas. A interrupção global da Cloudflare em julho de 2019 foi um regex fazendo exatamente isso. Mitigações: evite quantificadores aninhados, use grupos atômicos (?&gt;...) ou quantificadores possessivos em sabores que os suportam, ou use um motor de tempo linear como o regex do Rust ou RE2 do Google.

Related

Published May 31, 2026