62 votes

La reconnaissance par expression régulière d'une adresse électronique est-elle difficile ?

J'ai récemment lu quelque part que l'écriture d'une regexp pour faire correspondre une adresse électronique, en tenant compte de toutes les variations et possibilités de la norme, est extrêmement difficile et beaucoup plus compliquée que ce que l'on pourrait supposer au départ.

Pourquoi ça ?

Existe-t-il des expressions rationnelles connues et éprouvées qui réalisent pleinement cette tâche ?

Quelles sont les bonnes alternatives à l'utilisation de regexps pour faire correspondre les adresses électroniques ?

0 votes

Quelque chose d'intéressant à propos de l'expression régulière Email codinghorror.com/blog/archives/000214.html

0 votes

Si vous souhaitez simplement faire correspondre des modèles d'e-mails courants, vous pouvez consulter certaines des expressions suivantes aquí .

0 votes

Je pense que ce que vous avez lu ne concerne pas la "validation d'une adresse électronique selon la norme", mais plutôt la "validation d'une adresse électronique réelle". La différence n'est pas subtile, même si la formulation l'est. Actuellement, les réponses ci-dessous sont un mélange des deux. Peut-être pourriez-vous clarifier la question ?

65voto

Marc Gravell Points 482669

Pour le officiel e-mail spec, oui, c'est techniquement impossible via Regex en raison de la récursion de choses comme les commentaires (surtout si vous ne supprimez pas d'abord les espaces blancs des commentaires), et des différents formats (une adresse e-mail n'est pas toujours someone@somewhere.tld). On peut s'en approcher (avec des motifs Regex massifs et incompréhensibles), mais une bien meilleure façon de vérifier un e-mail est de procéder à la très familière poignée de main :

  • ils vous disent leur e-mail
  • vous leur envoyez par e-mail un lien de confimation avec un guide.
  • quand ils cliquent sur le lien, vous le savez :

    1. l'e-mail est correct
    2. il existe
    3. ils en sont les propriétaires

Bien mieux que d'accepter aveuglément une adresse électronique.

8 votes

Un bon conseil, si vous écrivez un site web, ne fonctionne pas si bien si vous écrivez un serveur/client de messagerie :-)

5 votes

Si vous écrivez un client ou un serveur de messagerie, vous ne devriez pas simuler l'analyse de la seule chose que vous devez analyser (à peu près).

1 votes

Comment leur envoyer un e-mail de confirmation sans accepter aveuglément leur adresse e-mail ?

22voto

mmaibaum Points 1081

Il existe un certain nombre de modules Perl (par exemple) qui font cela. N'essayez pas d'écrire votre propre regexp pour le faire. Regardez

Mail::VRFY fera des vérifications syntaxiques et de réseau (est-ce qu'un serveur SMTP quelque part accepte cette adresse)

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

RFC::RFC822::Address - un analyseur d'adresses électroniques à descente récursive.

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

Mail::RFC822::Address - validation d'adresse basée sur regexp, qui vaut la peine d'être regardée juste pour la folie de regexp

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

Des outils similaires existent pour d'autres langues. Regexp fou ci-dessous...

(?:(?:\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*)

1 votes

Je me souviens de quelqu'un qui disait que les expressions rationnelles étaient à la fois stupides (générées automatiquement) et mauvais . Quelqu'un d'autre s'en souvient-il ?

1 votes

Cela ne me surprendrait pas pour être honnête - ceci dit, toutes les tentatives de validation d'un email par regexp selon la norme actuelle que j'ai vues étaient plus ou moins folles - je n'essaierais même pas de comprendre celle-là. Une regexp d'un dixième de sa taille signifie probablement que vous ne devriez pas l'utiliser ;)

31 votes

Je classerais ceci dans la catégorie "cryptographie".

11voto

JacquesB Points 19878

La validation des adresses e-mail n'est pas vraiment utile de toute façon. Elle ne permet pas de détecter les fautes de frappe courantes ou les adresses électroniques inventées, car celles-ci ont tendance à ressembler syntaxiquement à des adresses valides.

Si vous voulez être sûr qu'une adresse est valide, vous n'avez pas d'autre choix que d'envoyer un courrier de confirmation.

Si vous voulez simplement vous assurer que l'utilisateur saisit quelque chose qui ressemble à une adresse électronique plutôt qu'un simple "asdf", vérifiez la présence d'un @. Une validation plus complexe n'apporte pas vraiment d'avantage.

(Je sais que cela ne répond pas à vos questions, mais je pense que cela vaut la peine de le mentionner quand même)

3 votes

Je pense que cela répond à la question.

0 votes

J'aime aussi vérifier qu'il n'y a qu'un seul caractère @ et qu'il ne s'agit pas du premier ou du dernier caractère. Lorsque je sais que l'adresse électronique sera une adresse électronique au format "typique" (par exemple UserName@DomainName.com), j'aime aussi vérifier qu'il y a au moins un caractère après le caractère @, suivi d'un caractère . ("point") suivi d'au moins un caractère.

2 votes

@Adam : Si vous vous engagez dans cette voie, vous devez le faire correctement. Voir par exemple l'explication de janm sur la façon dont vous pouvez avoir plus d'un @ dans une adresse électronique valide.

8voto

Dominic Sayers Points 1148

J'ai maintenant rassemblé les cas de test de Cal Henderson, Dave Child, Phil Haack, Doug Lovell et RFC 3696. 158 adresses de test en tout.

J'ai effectué tous ces tests avec tous les validateurs que j'ai pu trouver. La comparaison est ici : http://www.dominicsayers.com/isemail

J'essaierai de tenir cette page à jour au fur et à mesure que les gens améliorent leurs validateurs. Merci à Cal, Dave et Phil pour leur aide et leur coopération dans la compilation de ces tests et pour leurs critiques constructives de mon propre validateur .

Les gens doivent être conscients de la errata contre RFC 3696 en particulier. Trois des exemples canoniques sont en fait des adresses invalides. Et la longueur maximale d'une adresse est de 254 ou 256 caractères, no 320.

8voto

janm Points 9310

Il existe une grammaire libre de contexte en BNF qui décrit les adresses électroniques valides en RFC-2822 . Elle est complexe. Par exemple :

" @ "@example.com

est une adresse électronique valide. Je ne connais pas de regexps qui le font complètement ; les exemples habituellement donnés nécessitent que les commentaires soient d'abord supprimés. J'ai écrit un analyseur descendant récursif pour le faire complètement une fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X