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 Buğra SözeriPublished
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 depxsem incluirpxna correspondência. - Lookahead negativo
(?!...)— “não seguido por.”foo(?!bar)corresponde afoonão seguido debar. - 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) fazString.matchretornar todas as correspondências, masString.replacese 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
repadrão é próximo do PCRE menos alguns recursos. O módulo de terceirosregexadiciona 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
regexdo 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 (?>...) 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
- Testador de regex (ao vivo)Cole um padrão e uma amostra; veja correspondências, capturas e explicações em tempo real
- Codificação/decodificação de URLFerramenta complementar para a seção de padrões de URL
- Gerador UUIDGere UUIDs v4 / v7 que correspondem aos padrões abaixo
- Conversor de timestampÚtil quando o regex é a parte fácil de uma tarefa de análise de data
Published May 31, 2026