Skip to content
Comece com 100 créditos de verificação grátis
Qualisend
Todos os artigos
Engenharia / 27 de maio de 2026

Por que a validação de e-mail por regex falha

10 min de leitura

Qualisend team
Por que a validação de e-mail por regex falha

Toda base de código tem uma: uma expressão regular, copiada do Stack Overflow, que "valida" endereços de e-mail. Parece uma verificação, mas responde a uma pergunta que quase ninguém está realmente fazendo. Um regex consegue dizer que uma string tem o formato de um endereço de e-mail. Ele não consegue dizer se o endereço existe, se aceita mensagens ou se não vai gerar um hard bounce na sua próxima campanha — e essas são as únicas coisas que importam.

A resposta curta#

Regex valida sintaxe, não entregabilidade. definitely-fake@gmail.com é um endereço de e-mail perfeitamente válido por qualquer regex já escrito, e ele vai gerar bounce no instante em que você enviar para ele. Pior ainda, os regexes que as pessoas costumam usar ou rejeitam endereços reais (rígidos demais) ou aceitam qualquer bobagem (permissivos demais), e aquele que é tecnicamente correto ocupa centenas ou milhares de caracteres e ainda assim não consegue confirmar uma caixa de correio. Use uma verificação de sintaxe simples para pegar erros de digitação no input e depois verifique a entregabilidade com uma checagem de DNS e SMTP — que é um problema de rede, não de correspondência de padrões.

O regex que você já viu, e o que ele deixa passar#

Aqui está o arquétipo — alguma variante dele vive na maioria dos projetos:

const re = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
re.test("definitely-fake@gmail.com"); // true  ← will hard-bounce
re.test("typo@gmial.com");            // true  ← typo'd domain, bounces
re.test("info@company-that-folded.com"); // true  ← dead domain

Todos os três passam. Todos os três são não entregáveis. O regex fez seu trabalho perfeitamente e não te disse nada de útil, porque sintaxe e entregabilidade são perguntas diferentes. Todo endereço que um regex consegue enxergar é uma string; se há um humano lendo mensagens nele é um fato sobre a internet, não sobre a string.

Nenhum padrão consegue pegar um domínio digitado errado como gmial.com; isso exige uma comparação com provedores conhecidos. Veja os erros de digitação de e-mail mais comuns ou experimente o verificador de erros de digitação gratuito.

Os endereços que regexes rígidos rejeitam por engano#

Padrões rígidos falham no sentido oposto. Este padrão típico, "mais apertado", rejeita todos os endereços válidos da tabela abaixo:

const STRICT = /^[\w.-]+@\w+\.[a-z]{2,4}$/i;
EndereçoSuposição falsaRealidade
jane+news@example.comA parte local só tem letras, dígitos, pontos, hifens e underscoresO endereçamento com sinal de mais é permitido; o Gmail e muitos outros entregam mensagens +tag na caixa de correio base
o'brien@example.comNomes não têm pontuaçãoO apóstrofo é um caractere permitido na parte local
jane@studio.photographyTLDs têm de 2 a 4 letrasTLDs longos como .photography estão no ar há anos
jane@mail.example.co.ukUm domínio é um nome mais um TLD.co.uk e subdomínios de e-mail acrescentam rótulos
jane@my-company.comDomínios só têm letras e dígitosHifens são permitidos dentro de um rótulo

Cada rejeição é uma pessoa real barrada no cadastro, e nenhuma delas aparece nos seus logs de bounce, por isso padrões rígidos demais sobrevivem por anos. A verificação de sintaxe mais abaixo aceita todos os cinco.

O labirinto da RFC 5322#

"Tudo bem", diz o raciocínio, "vou usar um regex correto." A gramática formal para um endereço de e-mail é definida pela RFC 5322, e um regex que realmente a implementa é notoriamente monstruoso: de centenas a milhares de caracteres, e ele permite coisas que você nunca iria querer aceitar, como partes locais entre aspas com espaços ("a b"@example.com) e comentários dentro do endereço.

Daí surgem dois problemas. Primeiro, o regex rígido aceita mais do que você quer, não menos — ele está validando contra uma especificação de 2008, não contra "endereços para os quais servidores de e-mail reais vão de fato entregar". Segundo, mesmo uma correspondência RFC 5322 impecável ainda não consegue dizer se o domínio tem um servidor de e-mail ou se a caixa de correio existe. Você gastou um esforço enorme para responder à pergunta fácil com mais precisão, enquanto a pergunta difícil — a mensagem vai chegar? — continua completamente intocada.

Limites de tamanho: 64, 255 e 254#

A RFC 5321, o padrão SMTP, limita a parte local (antes do @) a 64 octetos, o domínio a 255 e o caminho inteiro a 256, incluindo os sinais de menor e maior em volta do endereço (<jane@example.com>). Isso deixa um teto real de 254 caracteres para o endereço em si.

Alguns dos nossos guias por linguagem verificam length <= 320 (64 + 1 + 255) em vez disso. É folgado, mas inofensivo: tudo o que essa checagem rejeita é de fato longo demais, e qualquer endereço acima de 254 caracteres que ela deixe passar ainda precisa superar as verificações de DNS e SMTP.

As três coisas que o regex fundamentalmente não consegue fazer#

Nenhum padrão, por mais engenhoso que seja, consegue atravessar a rede. O regex não consegue:

  • Verificar se o domínio pode receber mensagens. user@company-that-folded.com tem sintaxe válida em um domínio sem registros MX. Só uma consulta DNS revela o domínio morto.
  • Confirmar se a caixa de correio existe. noreply-9f2x@gmail.com tem sintaxe válida para uma conta que nunca foi criada. Só uma conversa SMTP com o Gmail pode te dizer que ela não está lá.
  • Detectar um domínio catch-all. Um servidor catch-all aceita todos os endereços, então nem mesmo uma checagem SMTP ao vivo consegue confirmar uma caixa de correio específica — e um regex não faz a menor ideia de que o domínio se comporta assim.

Essas não são lacunas de um regex específico; elas estão fora do que qualquer regex consegue fazer, porque são perguntas sobre servidores, não sobre strings. Respondê-las é trabalho da verificação de e-mail, que consulta a rede, não a string.

O que fazer de fato: validar em camadas#

A entregabilidade é uma sequência de verificações cada vez mais caras, e a sintaxe é apenas o primeiro estágio barato (o quadro completo está em como funciona a verificação de e-mail):

  1. Sintaxe — uma verificação simples no input para pegar erros de digitação óbvios. Essa é a única camada à qual o regex pertence.
  2. Domínio e MX — uma consulta DNS para confirmar se o domínio pode receber mensagens em algum grau. Veja os guias de Node.js e Python para código funcional.
  3. Sondagem SMTP da caixa de correio — a conversa de entrega que de fato confirma a caixa de correio, além da detecção de catch-all. Isso exige um servidor de e-mail com uma reputação de IP limpa e uma limitação de taxa cuidadosa, e é por isso que a maioria das equipes recorre a uma API de verificação em vez de construí-la. Provar que a pessoa é dona do endereço é outro trabalho, o de um e-mail de double opt-in.

A verificação de sintaxe que vale a pena manter#

Para a camada 1, não escreva a RFC 5322 na mão. O caminho pragmático é o input de e-mail HTML5 no navegador (que aplica o padrão do WHATWG living standard de graça) e uma verificação curta e permissiva no servidor:

// Pragmatic: rejects fat-finger errors, accepts the addresses real
// mail servers actually deliver to. Not a deliverability check.
const SYNTAX = /^[^\s@."]+(?:\.[^\s@."]+)*@[^\s@.]+(?:\.[^\s@.]+)+$/;

function isPlausibleEmail(email) {
  return (
    email.length <= 254 &&      // RFC 5321 path limit
    email.indexOf("@") <= 64 && // local part limit
    SYNTAX.test(email)
  );
}

isPlausibleEmail("jane@example.com");             // true
isPlausibleEmail("jane+news@mail.example.co.uk"); // true
isPlausibleEmail("not-an-email");                 // false
isPlausibleEmail("a@@b.com");                     // false
isPlausibleEmail("a..b@x.com");                   // false: consecutive dots
isPlausibleEmail(".a@x.com");                     // false: leading dot
isPlausibleEmail("a.@x.com");                     // false: trailing dot

Use-a para dar feedback instantâneo no teclado — nada além disso. Trate um resultado positivo como "vale a pena verificar direito", nunca como "válido".

O ponto fica fora da classe da parte local, então só pode aparecer entre caracteres. Isso rejeita os três erros com pontos, aceita os cinco endereços da tabela de regexes rígidos e mantém o padrão rápido. A verificação do navegador é uma conveniência, não uma barreira: qualquer pessoa pode enviar dados direto para o seu endpoint, então repita a verificação no servidor.

ReDoS: quando o regex de e-mail é a vulnerabilidade#

Um padrão mal construído também pode travar o seu serviço. Os motores nativos de JavaScript e Python fazem backtracking: quando uma correspondência falha, eles tentam todas as outras formas de o padrão dividir a entrada. Se um grupo repetido consegue casar com os mesmos caracteres que a parte anterior, o número de divisões cresce exponencialmente.

Versões anteriores desta página recomendavam esse formato, [^\s@"]+(?:\.[^\s@"]+)*, em que o ponto cabe tanto na classe quanto no separador do grupo. Em uma string de a. repetidos sem @, cada ponto a mais praticamente dobrava o tempo de execução no nosso próprio teste rápido em Node, e uma entrada com menos de 60 caracteres travava o processo por segundos. Isso é ReDoS (CWE-1333). Se você copiou o padrão antigo, troque-o pelo padrão acima.

Três correções:

  • Classes que não se sobrepõem. Com o ponto fora das classes, só existe uma forma de ler qualquer entrada, então o padrão acima roda em tempo linear.
  • Um motor de tempo linear. O pacote regexp do Go garante isso, e bindings de RE2 levam o mesmo para Node e Python.
  • Um parser em vez de um padrão, como o net/mail.ParseAddress do Go. Mantenha o Go atualizado: versões anteriores a 1.24.8 e 1.25.2 processam devagar literais de domínio muito longos.

Limitar o tamanho não vai te salvar: esse formato trava bem abaixo de 254 caracteres. Para testar a falha, meça o tempo de uma string que não casa, como "a.".repeat(25) + "!": um padrão vulnerável leva uma fração de segundo perceptível, e um seguro responde na hora.

Verificações de sintaxe por linguagem#

A maioria das stacks já traz uma verificação de sintaxe, então você raramente precisa de um padrão próprio. Cada guia cobre as três camadas; esta tabela mostra só a camada 1.

StackVerificação de sintaxe
Node.jsO regex acima
Expressexpress-validator isEmail()
Next.jszod z.string().email()
PythonO regex acima
Djangovalidate_email ou EmailField
FlaskWTForms Email()
PHPfilter_var() com FILTER_VALIDATE_EMAIL
Laravelemail:rfc,dns (sintaxe mais uma checagem de DNS da rota de e-mail)
Gonet/mail.ParseAddress
JavaJakarta Mail InternetAddress
Spring BootJakarta Bean Validation @Email
C#MailAddress.TryCreate
ASP.NET Core[EmailAddress]
RubyURI::MailTo::EMAIL_REGEXP
Railsformat com URI::MailTo::EMAIL_REGEXP

As funções nativas divergem nos casos extremos, como nomes de exibição (Jane <jane@example.com>); cada guia cobre as particularidades da sua stack.

Percorrendo o resto do caminho#

Depois que a sintaxe passa, a verificação de verdade é um trabalho de rede. Você pode construir as camadas de DNS e SMTP você mesmo — os guias por linguagem acima mostram até onde dá para chegar — mas confirmar caixas de correio ao vivo em escala esbarra na porta 25 estar bloqueada na maioria dos provedores, na reputação de IP e no greylisting, que é onde uma API gerenciada mostra seu valor. O POST /verify da Qualisend executa toda a sequência e retorna um veredito de quatro vias (deliverable | risky | undeliverable | unknown) com um código de motivo, para que seu código aja com base em se a caixa de correio existe, e não em se a string tem um @.

Perguntas frequentes

01Existe um regex correto para validação de e-mail?

Não no sentido que as pessoas gostariam. Existe um regex que implementa a RFC 5322, mas ele ocupa centenas ou milhares de caracteres, aceita formas exóticas que você nunca iria querer e ainda assim não consegue confirmar se o endereço é entregável. Para uso prático, um padrão curto e permissivo (ou o input HTML5 type="email") para pegar erros de digitação é a quantidade certa de regex - o resto é um problema de DNS e SMTP.

02Por que meu regex rejeita endereços de e-mail válidos?

Porque padrões rígidos embutem suposições que endereços reais quebram, como domínios de topo de duas a quatro letras (.photography tem onze) ou a ausência de sinais de mais na parte local. Um regex rígido demais é uma fonte comum de cadastros perdidos. Seja permissivo na sintaxe e verifique a entregabilidade separadamente.

03Qual é o tamanho máximo de um endereço de e-mail?

254 caracteres. A RFC 5321 limita a parte antes do @ a 64 caracteres e o domínio a 255, e limita o caminho SMTP inteiro a 256, incluindo os sinais de menor e maior em volta do endereço. Tirando esses dois sinais, sobram 254 para o endereço em si. Checagens que aceitam até 320 (64 + 1 + 255) são mais folgadas, mas inofensivas.

04A validação de e-mail do HTML5 verifica se o endereço é real?

Não. A validação type="email" do navegador é uma verificação de sintaxe - uma versão mais amigável e padronizada da mesma correspondência de padrões. Ela pega sinais de @ faltando e defeitos óbvios no input, mas nunca entra em contato com o servidor de e-mail, então não consegue dizer se o domínio ou a caixa de correio existe.

05O que eu deveria usar no lugar do regex para validar e-mails?

Faça em camadas: uma verificação de sintaxe permissiva para feedback instantâneo, uma consulta DNS/MX para descartar domínios mortos e uma sondagem SMTP da caixa de correio para confirmar a entrega. Construa as duas primeiras você mesmo; use uma API de verificação para a camada SMTP, já que fazer isso de forma confiável exige reputação de IP de envio e limitação de taxa que um regex jamais poderia oferecer.


Quer ver a diferença entre "sintaxe válida" e "vai de fato entregar"? O plano gratuito inclui 100 créditos de verificação que executam a sequência completa — sintaxe, DNS e a sondagem SMTP da caixa de correio — para que você possa ver um endereço aprovado pelo regex voltar como undeliverable. Sem conta, cole typo@gmial.com no verificador de e-mail gratuito: todos os regexes desta página aceitam o endereço, e o verificador sugere gmail.com. A referência da API tem exemplos de copiar e colar em sete linguagens.

Sua reputação, protegida.

Limpe sua primeira lista em minutos. 100 créditos grátis, sem cartão.

Começar