Regexp reconhecimento do endereço de e-mail duro?

Li recentemente em algum lugar que escrever um regexp para corresponder a um endereço de e-mail, levando em consideração todas as variações e possibilidades do padrão, é extremamente difícil e é significativamente mais complicado do que se supõe inicialmente.

Alguém pode fornecer algumas dicas sobre o porquê disso?

Existe alguma expressão conhecida e comprovada que realmente faça isso completamente?

Quais são algumas boas alternativas para usar regexps para correspondência de endereços de e-mail?

Para a especificação formal de e-mail, sim, é tecnicamente impossível via Regex devido à recursion de itens como comentários (especialmente se você não remover comentários para o espaço em branco primeiro) e os vários formatos diferentes (um endereço de e-mail não é sempre alguem@algum.tld). Você pode chegar perto (com alguns padrões Regex massivos e incompreensíveis), mas uma maneira muito melhor de verificar um e-mail é fazer um aperto de mão muito familiar:

  • eles te dizem seu e-mail
  • você e-mail deles um link de confimação com um Guid
  • quando clicam no link você sabe que:

    1. o e-mail está correto
    2. isso existe
    3. eles possuem

Muito melhor do que aceitar cegamente um endereço de e-mail.

Existem vários módulos Perl (por exemplo) que fazem isso. Não tente escrever seu próprio regexp para fazer isso. Olhe para

Mail::VRFY fará verificações de syntax e de rede (o servidor SMTP aceita algum lugar nesse endereço)

https://metacpan.org/pod/Mail::VRFY

RFC::RFC822::Address – um analisador de endereço de email de descida recursiva.

https://metacpan.org/pod/RFC::RFC822::Address

Mail::RFC822::Address – validação de endereço baseado em regexp, que vale a pena olhar apenas para o regexp insano

http://ex-parrot.com/~pdw/Mail-RFC822-Address.html

Existem ferramentas semelhantes para outros idiomas. Regexp insano abaixo …

 (?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:( ?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\ ](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\< (?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t] )*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])* )(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t ]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031 ]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]( ?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(? :(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(? :\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(? :(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]| \\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<> @,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|" (?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(? :[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[ \]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000- \031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|( ?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\< (?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,; :\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([ ^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\" .\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\ ]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\ [\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\ r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\] |\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0 00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\ .|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@, ;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(? :[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[ ^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\] ]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*( ?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:( ?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[ \["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t ])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t ])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(? :\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\ ]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\< (?:(?:\r\n) ?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<> @,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@, ;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t] )*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\". \[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[ "()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\ .(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:( ?:\r\n)?[ \t])*))*)?;\s*) 

Validar endereços de e-mail não é muito útil de qualquer maneira. Ele não detecta erros comuns ou endereços de e-mail inventados, pois eles tendem a se parecer sintaticamente com endereços válidos.

Se você quiser ter certeza de que um endereço é válido, você não tem escolha a não ser enviar um email de confirmação.

Se você quiser apenas ter certeza de que o usuário insira algo que parece um e-mail, em vez de apenas “asdf”, verifique se há um @. Uma validação mais complexa não fornece realmente nenhum benefício.

(Eu sei que isso não responde às suas perguntas, mas acho que vale a pena mencionar)

Eu colecionei casos de teste de Cal Henderson, Dave Child, Phil Haack, Doug Lovell e RFC 3696. 158 endereços de teste em todos.

Eu executei todos esses testes contra todos os validadores que consegui encontrar. A comparação está aqui: http://www.dominicsayers.com/isemail

Tentarei manter essa página atualizada enquanto as pessoas aprimoram seus validadores. Obrigado a Cal, Dave e Phil por sua ajuda e cooperação na compilation desses testes e críticas construtivas de meu próprio validador .

As pessoas devem estar cientes da errata contra o RFC 3696 em particular. Três dos exemplos canônicos são, na verdade, endereços inválidos. E o comprimento máximo de um endereço é de 254 ou 256 caracteres, não 320.

No entanto, nem tudo é tolice, já que permitir caracteres como ‘+’ pode ser muito útil para os usuários que combatem spam, por exemplo, myemail+sketchysite@gmail.com ( endereços do Gmail descartáveis ​​instantâneos ).

Somente quando um site aceita isso.

Existe uma gramática livre de contexto no BNF que descreve endereços de e-mail válidos no RFC-2822 . É complexo. Por exemplo:

 " @ "@example.com 

é um endereço de email válido. Eu não sei de nenhum regexps que faça isso completamente; os exemplos geralmente fornecidos exigem que os comentários sejam retirados primeiro. Eu escrevi um analisador de descendência recursiva para fazer isso completamente uma vez.

A aceitação ou não de formatos de endereço de e-mail incomuns e bizarros depende, na minha opinião, do que se quer fazer com eles.

Se você está escrevendo um servidor de e-mail, você tem que ser muito exato e incrivelmente correto no que você aceita. O regex “insano” citado acima é, portanto, apropriado.

Para o resto de nós, porém, estamos principalmente interessados ​​em garantir que algo que um usuário digita em um formulário da Web pareça razoável e não tenha algum tipo de injeção de SQL ou estouro de buffer nele.

Francamente, alguém realmente se preocupa em permitir que alguém insira um endereço de e-mail de 200 caracteres com comentários, novas linhas, citações, espaços, parênteses ou outro texto sem sentido ao se inscrever em uma lista de correspondência, boletim informativo ou site? A resposta apropriada para esses palhaços é “Volte mais tarde quando você tiver um endereço que se parece com username@domain.tld“.

A validação que faço consiste em garantir que exista exatamente um ‘@’; que não há espaços, nulos ou novas linhas; que a parte à direita do ‘@’ tem pelo menos um ponto (mas não dois pontos seguidos); e que não há citações, parênteses, vírgulas, pontos-e-vírgulas, pontos de exclamação, ponto-e-vírgula ou barras invertidas, sendo mais provável que sejam tentativas de hackery do que partes de um endereço de e-mail real.

Sim, isso significa que estou rejeitando endereços válidos com os quais alguém pode tentar se registrar em meus sites – talvez eu “rejeite” incorretamente até 0,001% dos endereços do mundo real! Eu posso viver com isso.

As citações e várias outras partes raramente usadas, mas válidas, do RFC tornam isso difícil. Eu não sei o suficiente sobre este tópico para comentar definitivamente, além de “é difícil” – mas felizmente outras pessoas escreveram sobre isso por completo.

Quanto a um regex válido para ele, o módulo Perl Mail :: Rfc822 :: Address contém uma expressão regular que aparentemente funcionará – mas somente se algum comentário já tiver sido substituído pelo espaço em branco. (Comentários em um endereço de e-mail? Você vê porque é mais difícil do que se poderia esperar …)

Naturalmente, as expressões regulares simplificadas que abundam em outros lugares validarão quase todos os endereços de e-mail que estão sendo usados ​​genuinamente …

Alguns sabores de regex podem realmente corresponder a colchetes nesteds (por exemplo, aqueles compatíveis com Perl). Dito isso, vi um regex que afirma corresponder corretamente a RFC 822 e era duas páginas de texto sem nenhum espaço em branco. Portanto, a melhor maneira de detectar um endereço de email válido é enviar email para ele e ver se funciona.

Apenas para adicionar uma regex que é menos louca do que a listada por @mmaibaum:

 ^[a-zA-Z]([.]?([a-zA-Z0-9_-]+)*)?@([a-zA-Z0-9\-_]+\.)+[a-zA-Z]{2,4}$ 

Ele não é à prova de balas e certamente não cobre toda a especificação de e-mail, mas faz um trabalho decente de atender à maioria dos requisitos básicos. Melhor ainda, é um pouco compreensível e pode ser editado.

Cribbed de uma discussão em HouseOfFusion.com , um recurso de ColdFusion de class mundial.

Uma maneira fácil e boa de verificar os endereços de e-mail em Java é usar o EmailValidator da biblioteca Apache Commons Validator .

Eu sempre verifico um endereço de e-mail em um formulário de input contra algo assim antes de enviar um e-mail – mesmo se você só pegar alguns erros de digitação. Você provavelmente não quer escrever um scanner automatizado para mensagens de notificação de “falha na entrega”. 🙂

É muito difícil porque há muitas coisas que podem ser válidas em um endereço de e-mail, de acordo com o Email Spec, RFC 2822 . Coisas que você normalmente não vê como + são caracteres perfeitamente válidos para um endereço de e-mail .. de acordo com as especificações.

Há uma seção inteira dedicada aos endereços de e-mail em http://regexlib.com , que é um ótimo recurso. Eu sugiro que você determine quais critérios são importantes para você e encontre um que corresponda. A maioria das pessoas realmente não precisa de suporte total para todas as possibilidades permitidas pela especificação.

Se você estiver executando no .NET Framework, tente instanciar um object MailAddress e capturar o FormatException se ele explodir ou retirar o Address se ele for bem-sucedido. Sem entrar em qualquer bobagem sobre o desempenho de captura de exceções (na verdade, se isso é apenas em um único formulário da Web não vai fazer muita diferença), a class MailAddress no .NET framework passa por uma análise bastante completa processo (não usa um RegEx). Abra o Reflector e procure por MailAddress e MailBnfHelper.ReadMailAddress() para ver todas as coisas de fantasia que ele faz. Alguém mais esperto do que eu passou muito tempo construindo esse analisador na Microsoft, eu vou usá-lo quando eu realmente enviar um e-mail para esse endereço, então eu também posso usá-lo para validar o endereço de input também.

Muitos tentaram e muitos chegam perto. Você pode querer ler o artigo da wikipedia , e alguns outros .

Especificamente, você vai querer lembrar que muitos sites e servidores de e-mail relaxaram a validação de endereços de e-mail, então, essencialmente, eles não implementam totalmente o padrão. É bom o suficiente para o e-mail funcionar o tempo todo.

Tente este:

 "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])" 

Dê uma olhada aqui para os detalhes.

No entanto, em vez de implementar o padrão RFC822, talvez seja melhor analisá-lo de outro ponto de vista. Realmente não importa o que o padrão diz se os servidores de email não espelharem o padrão. Então, eu diria que seria melhor imitar o que os servidores de e-mail mais populares fazem ao validar endereços de e-mail.

Esta class para Java possui um validador: http://www.leshazlewood.com/?p=23

Isto é escrito pelo criador de Shiro (formalmente Ki, formalmente JSecurity)

Os prós e contras de testar a validade do endereço de email:

Existem dois tipos de regexes que validam e-mails:

  1. Aqueles que são muito soltos.
  2. Aqueles que são muito rigorosos.

Não é possível que uma expressão regular corresponda a todos os endereços de e-mail válidos e não a endereços de e-mail que não sejam válidos, pois algumas strings podem se parecer com endereços de e-mail válidos, mas não chegam à checkbox de input de ninguém. A única maneira de testar se um e-mail é realmente válido é enviar um e-mail para esse endereço e ver se você recebe algum tipo de resposta. Com isso em mente, os regexes que são muito rígidos em correspondência de e-mails não parecem ter muito propósito.

Eu acho que a maioria das pessoas que pedem um e-mail regex estão procurando pela primeira opção, regexes que são muito frouxas. Eles querem testar uma string e ver se ela se parece com um e-mail, se definitivamente não é um e-mail, então eles podem dizer ao usuário: “Ei, você deveria colocar um e-mail aqui e isso definitivamente é não é um e-mail válido. Talvez você não tenha percebido que esse campo é para um e-mail ou talvez haja um erro de digitação “.

Se um usuário coloca uma string que se parece muito com um e-mail válido, mas na verdade não é uma, então esse é um problema que deve ser tratado por uma parte diferente do aplicativo.

Alguém pode fornecer algumas dicas sobre o porquê disso?

Sim, é um padrão extremamente complicado que permite muitas coisas que ninguém usa atualmente. 🙂

Existe alguma expressão conhecida e comprovada que realmente faça isso completamente?

Aqui está uma tentativa de analisar completamente todo o padrão …

http://ex-parrot.com/~pdw/Mail-RFC822-Address.html

Quais são algumas boas alternativas para usar regexps para correspondência de endereços de e-mail?

Usando uma estrutura existente para isso em qualquer linguagem que você esteja usando, eu acho? Embora esses provavelmente usem o regexp internamente. É uma string complexa. Regexps são projetados para analisar strings complexas, então essa é realmente a sua melhor escolha.

Edit : devo acrescentar que o regexp que eu liguei foi apenas por diversão. Eu não endosso usando um regexp complexo como esse – algumas pessoas dizem que “se o seu regexp é mais do que uma linha, é garantido que ele tem um bug em algum lugar”. Eu me liguei a ele para ilustrar o quão complexo é o padrão.

Adicionando a resposta de Wayne , há também uma seção sobre http://www.regular-expressions.info dedicada ao email, com algumas amostras.

Você sempre pode questionar se vale a pena ou se, na verdade, qualquer regexp de cobertura menor que 100% só contribui para uma falsa sensação de segurança.

No final, enviar o e-mail é o que fornecerá a validação final real. (você descobrirá se o seu servidor de email tem erros 😉

Para completar este post, também para PHP existe uma function interna de linguagem para validar e-mails.

Para PHP Use o nice filter_var com o tipo específico de validação EMAIL 🙂

Não mais regexes de email insano no php: D

 var_dump(filter_var('bob@example.com', FILTER_VALIDATE_EMAIL)); 

http://www.php.net/filter_var