Regex para validação de e-mail que realmente funciona (2026)
A validação de e-mail parece simples até você sentar para escrevê-la. O que parece uma verificação de formato simples acaba envolvendo uma especificação RFC de 6.000 caracteres, nomes de domínio internacionais, strings entre aspas e casos extremos que quebram quase todos os regex que você encontra no Stack Overflow. Este guia cobre os padrões práticos que funcionam, os trade-offs entre eles e quando parar de tentar ser esperto com regex.
Por que a validação de e-mail é mais difícil do que você pensa
O formato de endereço de e-mail é definido pela RFC 5322 e seus predecessores. A especificação completa permite alguns endereços de aparência surpreendentemente estranha que são tecnicamente válidos:
"spaces in quotes"@example.com— strings entre aspas na parte localuser+tag@example.com— endereçamento plus (amplamente usado para filtros no Gmail)user@subdomain.example.co.uk— múltiplos subdomínios e ccTLDsuser@[192.168.1.1]— literais de endereço IP como domíniovery.unusual."@".unusual.com@example.com— tecnicamente válido mas quase nunca vistouser@xn--nxasmq6b.com— nomes de domínio internacionalizados (Punycode)
Um regex totalmente compatível com a RFC 5322 precisaria lidar com todos esses, enquanto também rejeita endereços que não cumprem as regras básicas de formato. O resultado é um padrão de 1000 caracteres que é essencialmente impossível de manter. Na prática, o objetivo não é a conformidade total com a RFC — é detectar erros de digitação sem bloquear endereços reais.
O regex simples (suficiente para 99% dos casos)
Para a maioria das aplicações, este padrão mínimo é a escolha certa. Ele valida a estrutura essencial — algo antes de um @, um domínio e um TLD — sem falsos negativos em endereços legítimos:
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
Detalhamento:
^— início da string[^\s@]+— um ou mais caracteres que não são espaço em branco nem@(a parte local)@— arroba literal[^\s@]+— um ou mais caracteres que não são espaço em branco nem@(o domínio)\.— um ponto literal[^\s@]+— um ou mais caracteres (o TLD)$— fim da string
O que ele aceita e rejeita corretamente:
Válidos (aceitos):
Inválidos (rejeitados):
A principal fraqueza é que ele aceita user@@example.com e a@b.c (tecnicamente válido mas suspeito). Para a maioria dos formulários de cadastro e inputs de API, esse é um trade-off aceitável.
O regex completo (compatível com RFC 5322)
Quando você precisa de uma validação mais rigorosa — por exemplo, em um sistema de envio de e-mails onde endereços inválidos causam bounces e danificam a reputação do remetente — um padrão mais completo é justificado. Este é um padrão derivado da RFC 5322 amplamente citado:
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
Este padrão é mais longo mas lida com significativamente mais casos. Detalhamento das partes principais:
- Parte local (antes do @): Ou uma sequência de caracteres permitidos com segmentos opcionais separados por pontos
[^<>()...]+(\.[^<>()...]+)*, ou uma string entre aspas".+"para endereços como"john doe"@example.com. - Domínio (depois do @): Ou um literal de endereço IP entre colchetes
\[[0-9]{1,3}...\], ou um hostname padrão com um TLD de pelo menos 2 caracteres([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}. - TLD mínimo de 2 caracteres: Rejeita TLDs de um único caractere enquanto aceita os longos como
.museumou.technology.
Casos adicionais que este padrão lida corretamente:
Ainda rejeitados corretamente:
Validação de e-mail em JavaScript
Aqui estão implementações práticas em JavaScript prontas para copiar e colar usando ambos os padrões:
Função de validação simples
/** * Valida formato de e-mail para a maioria dos casos de uso. * Rápido, legível, muito poucos falsos negativos. */ function isValidEmail(email) { const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return pattern.test(email.trim()); } // Uso isValidEmail("user@example.com"); // true isValidEmail("not-an-email"); // false isValidEmail("user+tag@gmail.com"); // true
Validação mais rigorosa com feedback detalhado
function validateEmail(email) { const trimmed = email.trim(); if (!trimmed) { return { valid: false, error: "O e-mail é obrigatório" }; } if (trimmed.length > 254) { return { valid: false, error: "Endereço de e-mail muito longo (máximo 254 caracteres)" }; } if (!trimmed.includes("@")) { return { valid: false, error: "Falta o símbolo @" }; } const [local, ...domainParts] = trimmed.split("@"); const domain = domainParts.join("@"); if (!local || local.length > 64) { return { valid: false, error: "Parte local inválida (antes do @)" }; } if (!domain || !domain.includes(".")) { return { valid: false, error: "Domínio inválido (falta TLD)" }; } const rfcPattern = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!rfcPattern.test(trimmed)) { return { valid: false, error: "Formato de e-mail inválido" }; } return { valid: true, email: trimmed.toLowerCase() }; } // Uso const result = validateEmail(" User@Example.COM "); // { valid: true, email: "user@example.com" }
Validação de e-mail com HTML5
Antes de recorrer ao JavaScript, considere o que o navegador te oferece de graça. O elemento input type="email" tem validação embutida que é executada ao submeter o formulário:
<!-- Validação embutida básica --> <input type="email" name="email" required> <!-- Com padrão personalizado para validação mais rigorosa --> <input type="email" name="email" required pattern="[^\s@]+@[^\s@]+\.[^\s@]+" title="Por favor, insira um endereço de e-mail válido" >
O algoritmo embutido do navegador para type="email" segue a especificação HTML5 (um subconjunto simplificado da RFC 5322). Ele rejeita não-e-mails óbvios, exibe um tooltip de validação nativo e funciona sem JavaScript. O atributo pattern permite adicionar restrições adicionais.
Limitações a considerar: a validação embutida só é acionada ao submeter o formulário, não enquanto o usuário digita. Para feedback em tempo real, você precisa de JavaScript. Além disso, a pseudo-classe CSS :invalid permite estilizar inputs inválidos, mas é acionada mesmo em campos vazios não tocados a menos que você também use :not(:placeholder-shown):
/* Só mostrar borda vermelha depois que o usuário interagiu */ input[type="email"]:not(:placeholder-shown):invalid { border-color: #ef4444; outline-color: #ef4444; } input[type="email"]:not(:placeholder-shown):valid { border-color: #34d399; }
Casos extremos comuns
Estes são os casos que fazem falhar a maioria das implementações de validação de e-mail:
Endereçamento plus (subaddressing)
user+tag@gmail.com é válido e amplamente usado. Gmail, Outlook e a maioria dos provedores de e-mail modernos suportam isso para filtragem. Sua regex não deve rejeitar o caractere + na parte local. Muitos padrões excessivamente restritivos falham nisso.
Subdomínios
first.last@mail.company.co.uk é um e-mail válido com pontos tanto na parte local quanto no domínio. O domínio tem três níveis. Um bom padrão deve lidar com múltiplos rótulos separados por pontos no domínio.
TLDs longos
TLDs não são mais restritos a dois ou três caracteres. .museum, .photography, .technology e centenas de outros gTLDs são válidos. Qualquer regex que imponha um comprimento máximo de TLD de 4 ou 6 caracteres produzirá falsos negativos. Imponha apenas um mínimo (2 caracteres) e nenhum máximo.
Domínios internacionais (IDN)
Nomes de domínio podem conter caracteres não-ASCII codificados como Punycode. user@münchen.de é válido — o domínio real é xn--mnchen-3ya.de na forma ASCII. A maioria dos padrões regex não consegue validar Punycode diretamente; confie em uma biblioteca dedicada de validação de e-mail se for necessário suporte a IDN.
Literais de endereço IP
user@[192.168.1.1] é tecnicamente válido segundo a RFC 5321 mas quase nunca é usado na prática. A menos que você esteja construindo uma implementação SMTP, pode ignorar este caso com segurança.
Não valide demais
Este é o conselho prático mais importante deste artigo: o propósito da validação de e-mail no lado do cliente é detectar erros de digitação, não verificar a capacidade de entrega.
Nenhum regex pode dizer se um endereço de e-mail realmente existe ou se sua caixa de entrada está aceitando mensagens. Somente entregar na caixa de entrada pode confirmar isso. Validar demais (rejeitar endereços que seu regex incorretamente marca como inválidos) perde usuários reais. Validar de menos (aceitar endereços mal formatados) te custa um bounce.
A abordagem correta é uma estratégia de duas camadas:
- Use um regex simples para detectar erros óbvios de formato (falta o
@, falta o TLD, espaços). - Envie um e-mail de confirmação ou verificação para confirmar que o endereço é real e o usuário o controla.
Um e-mail de confirmação é a única porta confiável. Todo o resto é uma heurística. Se você se encontrar debatendo se deve rejeitar user@localhost ou a@b.io, dê um passo atrás — envie o e-mail e deixe a camada SMTP lidar com isso.
Comparação de padrões regex populares para e-mail
Aqui está uma comparação prática dos padrões mais comumente usados, incluindo seus trade-offs:
| Padrão | Tipo | Vantagens | Desvantagens | Cobertura |
|---|---|---|---|---|
| /^[^\s@]+@[^\s@]+\.[^\s@]+$/ | Simples | Legível, mínimos falsos negativos, rápido | Aceita a@@b.c, muito permissivo |
~95% |
| /^[\w.+-]+@[\w-]+\.[\w.]{2,}$/ | Comum | Curto, lida com a maioria dos e-mails do mundo real | Rejeita caracteres especiais válidos na parte local | ~92% |
| /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ | Equilibrado | Amplamente usado, bom equilíbrio de rigor e cobertura | Rejeita alguns locais válidos com strings entre aspas | ~97% |
| /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}...)/ | RFC 5322 | Lida com strings entre aspas, literais IP, TLDs longos | Longo, difícil de ler, ainda não 100% compatível com RFC | ~99% |
O padrão "equilibrado" completo
O terceiro padrão na tabela acima é a escolha mais prática para uso em produção quando você quer mais do que o padrão simples mas não a complexidade completa da RFC 5322:
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
Detalhamento:
[a-zA-Z0-9._%+-]+— parte local: alfanuméricos mais.,_,%,+,-@— arroba obrigatório[a-zA-Z0-9.-]+— domínio: alfanuméricos, hífens, pontos (lida com subdomínios)\.— ponto separador antes do TLD[a-zA-Z]{2,}— TLD: pelo menos 2 letras, sem máximo (lida com TLDs longos)
Usar uma biblioteca em vez de criar a sua própria
Para aplicações onde a validade do e-mail é crítica (sistemas de e-mail transacional, fluxos de cadastro B2B SaaS), considere uma biblioteca de validação dedicada em vez de escrever regex você mesmo:
// Node.js — validator.js (a mais popular) import validator from 'validator'; validator.isEmail('user@example.com'); // true // Node.js — email-validator (leve) import { validate } from 'email-validator'; validate('user@example.com'); // true // Python — email-validator (compatível com RFC) # pip install email-validator from email_validator import validate_email, EmailNotValidError try: info = validate_email("user@example.com") except EmailNotValidError as e: print(str(e))
Teste sua regex de e-mail
A melhor forma de entender qualquer regex é executá-la contra um conjunto abrangente de entradas de teste — tanto endereços válidos que você espera aceitar quanto inválidos que precisa rejeitar. Nosso Regex Tester permite colar qualquer um dos padrões acima, construir um conjunto de testes e ver resultados de matching destacados em tempo real.
Teste sua regex de e-mail ao vivo
Cole qualquer padrão regex de e-mail e teste contra suas próprias entradas. Suporta flags, grupos de captura e matching multilinha. Roda inteiramente no seu navegador.
Abrir Regex Tester →Ferramentas de desenvolvimento relacionadas
- Regex Tester — teste e depure expressões regulares com destaque ao vivo
- Inspetor ENV — valide arquivos
.enve detecte segredos expostos - Codificador / Decodificador URL — codifique e decodifique componentes de URL e query strings
- Ver todas as ferramentas gratuitas para desenvolvedores