Comment valider une adresse email en utilisant une expression régulière?

au fil des ans, j'ai lentement développé une expression régulière qui valide la plupart des adresses e-mail correctement, en supposant qu'ils n'utilisent pas une adresse IP comme la partie serveur.

Je l'utilise dans plusieurs programmes PHP, et il fonctionne la plupart du temps. Cependant, de temps à autre, je suis contacté par quelqu'un qui ait des problèmes avec un site qui l'utilise, et je finis par avoir à faire quelques ajustements (plus récemment, j'ai réalisé que je n'étais pas permettre TLD à 4 caractères).

Quelle est la meilleure expression régulière que vous ayez ou ayez vue pour valider des courriels?

j'ai vu plusieurs solutions qui utilisent des fonctions qui utilisent plusieurs expressions plus courtes, mais je préférerais avoir une expression complexe longue dans une fonction simple au lieu de plusieurs expressions courtes dans une fonction plus complexe.

2969
demandé sur acrosman 2008-10-14 18:14:34

30 réponses

le entièrement conforme à la RFC 822 regex est inefficace et obscur en raison de sa longueur. Heureusement, la RFC 822 a été remplacée deux fois et la spécification actuelle pour les adresses email est RFC 5322 . RFC 5322 conduit à un regex qui peut être compris si étudié pendant quelques minutes et est assez efficace pour une utilisation réelle.

Un RFC 5322 conforme regex peut être trouvé dans le haut de la page à http://emailregex.com / mais utilise le patron d'adresse IP qui flotte autour de l'internet avec un bug qui permet 00 pour n'importe laquelle des valeurs décimales de byte non signées dans une adresse délimitée par un point, ce qui est illégal. Le reste semble être compatible avec la grammaire RFC 5322 et passe plusieurs tests en utilisant grep -Po , y compris les noms de domaine, les adresses IP, les mauvaises et les noms de comptes avec et sans guillemets.

Correction de la 00 bug dans le modèle IP, nous obtenons un regex fonctionnel et assez rapide. (Gratter la version rendue, pas le markdown, pour code.)

(?:[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])?/ \[(?: (?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3} (?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-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])+)\]

Voici diagramme de machine à état fini pour regexp ci-dessus qui est plus clair que regexp lui-même enter image description here

les modèles plus sophistiqués en Perl et PCRE (bibliothèque regex utilisée par exemple en PHP) peuvent correctement analyser RFC 5322 sans un problème . Python et C# peuvent le faire aussi, mais ils utilisent une syntaxe différente de celles des deux premiers. Toutefois, si vous êtes obligé d'utiliser l'un des langages les moins puissants d'appariement de motifs, alors il est préférable d'utiliser un vrai analyseur.

il est également important de comprendre que la validation selon la RFC ne vous dit absolument rien sur le fait que cette adresse existe réellement dans le domaine fourni, ou si la personne qui entre l'adresse est son véritable propriétaire. Signer des autres jusqu'à des listes de diffusion de cette façon tout le temps. Correction qui nécessite une validation plus sophistiquée qui implique l'envoi d'une adresse message comprenant un jeton de confirmation destiné à être saisi sur la même page web que l'adresse.

Les jetons de Confirmation

sont le seul moyen de savoir que vous avez l'adresse de la personne qui l'a saisi. C'est pourquoi la plupart des listes de diffusion utilisent maintenant ce mécanisme pour confirmer les inscriptions. Après tout, n'importe qui peut mettre president@whitehouse.gov , et cela se parlera même comme juridique, mais il est peu probable que ce soit la personne à l'autre bout.

pour PHP, vous devriez pas utiliser le modèle donné dans valider une adresse E - Mail avec PHP, la bonne façon à partir de laquelle je cite:

il y a un risque que l'usage courant et le codage inadéquat généralisé établissent une norme de fait pour les adresses de courriel qui est plus restrictive que la norme officielle consignée.

ce qui n'est pas mieux que tous les autres modèles non-RFC. Il n'est même pas assez intelligent pour manipuler même RFC 822 , encore moins RFC 5322. celui-ci , cependant, est.

si vous voulez obtenir fantaisie et pédant, mettre en œuvre un moteur d'état complet . Une expression régulière ne peut agir que comme un filtre rudimentaire. Le problème avec les expressions régulières est que le fait de dire à quelqu'un que son adresse e-mail parfaitement valide est invalide (un faux positif) parce que votre expression régulière ne peut pas le gérer est tout simplement grossier et impoli du point de vue de l'utilisateur. Un moteur d'État à cet effet peut à la fois valider et même corriger des adresses e-mail qui seraient autrement considérées comme invalides car il démonte l'adresse e-mail selon chaque RFC. Cela permet potentiellement plus agréable, comme

l'adresse e-mail spécifiée "myemail@address,com" n'est pas valide. Tu voulais dire ... myemail@address.com"?

voir aussi Validation des adresses Courriel , y compris les commentaires. Ou comparant L'adresse E-mail validant les Expressions régulières .

Regular expression visualization

Debuggex Démo

2103
répondu bortzmeyer 2017-05-23 12:26:29

vous ne devez pas utiliser d'expressions régulières pour valider les adresses e-mail.

à la place, utilisez la classe MailAddress , comme ceci:

try {
    address = new MailAddress(address).Address;
} catch(FormatException) {
    //address is invalid
}

la classe MailAddress utilise un analyseur BNF pour valider l'adresse en pleine conformité avec RFC822.

si vous voulez vraiment utiliser un regex, voici :

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

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

@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\".\[\] "151910920"0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\".\[\] "151910920"0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\
".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\".\[\] "151910920"0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\".
\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] "151910920"0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\".\[\]]))|"(?:[^\"\r\]|\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] "151910920"0-1]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\".\[\] "151910920"0-1]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\".\[\]]))|\[([^\[\]\r\]|\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)
708
répondu SLaks 2011-03-14 20:04:23

cette question est posée beaucoup, mais je pense que vous devriez prendre du recul et vous demander pourquoi vous voulez valider adresses email syntaxiquement? Quel est l'avantage vraiment?

  • il n'attrapera pas les fautes de frappe courantes.
  • cela n'empêche pas les gens d'entrer des adresses e-mail invalides ou inventées, ou d'entrer l'adresse d'une autre personne.

si vous voulez valider qu'un e-mail est correct, vous n'avez pas d'autre choix que d'envoyer un email de confirmation et d'avoir la réponse de l'utilisateur à cela. Dans de nombreux cas, vous aura pour envoyer un courrier de confirmation de toute façon pour des raisons de sécurité ou pour des raisons éthiques (par exemple, vous ne pouvez pas signer quelqu'un à un service contre leur volonté).

506
répondu JacquesB 2011-05-20 18:17:27

cela dépend de ce que vous voulez dire par meilleur: Si vous parlez d'attraper chaque adresse e-mail valide utiliser ce qui suit:

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

( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Si vous cherchez quelque chose de plus simple, mais qui va attraper les adresses email les plus valides essayer quelque chose comme:

"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"

EDIT: À partir du lien:

Cette expression régulière ne valider que les adresses dont les commentaires ont été effacés et remplacés par des espaces (ceci est fait par le module).

322
répondu Good Person 2012-03-17 22:28:16

tout dépend de la précision que vous voulez être. Pour mes besoins, où j'essaie juste d'empêcher des choses comme bob @ aol.com (Espaces Dans Les e-mails) ou steve (pas de domaine du tout) ou mary@aolcom (pas de période Avant .com), j'utilise

/^\S+@\S+\.\S+$/

bien sûr, il va correspondre à des choses qui ne sont pas des adresses e-mail valides, mais il s'agit de jouer la règle 90/10.

307
répondu Andy Lester 2016-06-28 17:24:49

[mise à jour] j'ai rassemblé tout ce que je sais sur la validation de l'adresse email ici: http://isemail.info , qui non seulement valide, mais aussi diagnostique des problèmes avec les adresses e-mail. Je suis d'accord avec beaucoup des commentaires ici que la validation n'est qu'une partie de la réponse; Voir mon essai à http://isemail.info/about .

is_email () reste, autant que je sache, le seul validateur qui vous dira définitivement si un chaîne donnée est une adresse de courriel valide ou pas. J'ai téléchargé une nouvelle version à http://isemail.info /

j'ai rassemblé des cas d'essai de Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 et RFC 3696. 275 adresses de test en tout. J'ai comparé tous ces tests avec tous les validateurs libres que j'ai pu trouver.

je vais essayer de garder cette page à jour alors que les gens améliorent leurs validateurs. Merci à Cal, Michael, Dave, Paul et Phil pour leur aide et leur coopération dans la compilation de ces tests et la critique constructive de mon propre validateur .

les gens devraient être au courant de la errata contre RFC 3696 en particulier. Trois des exemples canoniques sont en fait des adresses non valides. Et la longueur maximale d'une adresse est 254 ou 256 caractères, pas 320.

282
répondu Dominic Sayers 2014-09-03 13:35:34

Per the W3C HTML5 spec :

^[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])?)*$

Contexte:

Un adresse e-mail valide est une chaîne qui correspond à l'ABNF de production [...].

Note: cette exigence est une violation volontaire de RFC 5322 , qui définit une syntaxe pour les adresses e-mail qui est en même temps trop stricte (avant le caractère"@"), trop vague (après le caractère"@"), et trop laxiste (permettant des commentaires, des caractères d'espace, et des cordes citées d'une manière peu familière à la plupart des utilisateurs) pour être d'usage pratique ici.

l'expression régulière suivante compatible JavaScript et Perl est une implémentation de la définition ci - dessus.

/^[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])?)*$/

246
répondu Rory O'Kane 2013-09-24 15:52:21

c'est facile en Perl 5.10 ou plus récent:

/(?(DEFINE)
   (?<address>         (?&mailbox) | (?&group))
   (?<mailbox>         (?&name_addr) | (?&addr_spec))
   (?<name_addr>       (?&display_name)? (?&angle_addr))
   (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
   (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
                                          (?&CFWS)?)
   (?<display_name>    (?&phrase))
   (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

   (?<addr_spec>       (?&local_part) \@ (?&domain))
   (?<local_part>      (?&dot_atom) | (?&quoted_string))
   (?<domain>          (?&dot_atom) | (?&domain_literal))
   (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                 \] (?&CFWS)?)
   (?<dcontent>        (?&dtext) | (?&quoted_pair))
   (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

   (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#$%&'*+-/=?^_`{|}~])
   (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
   (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
   (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

   (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
   (?<quoted_pair>     \ (?&text))

   (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
   (?<qcontent>        (?&qtext) | (?&quoted_pair))
   (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                        (?&FWS)? (?&DQUOTE) (?&CFWS)?)

   (?<word>            (?&atom) | (?&quoted_string))
   (?<phrase>          (?&word)+)

   # Folding white space
   (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
   (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
   (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
   (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
   (?<CFWS>            (?: (?&FWS)? (?&comment))*
                       (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

   # No whitespace control
   (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

   (?<ALPHA>           [A-Za-z])
   (?<DIGIT>           [0-9])
   (?<CRLF>            \x0d \x0a)
   (?<DQUOTE>          ")
   (?<WSP>             [\x20\x09])
 )

 (?&address)/x
195
répondu Abigail 2013-07-30 02:21:37

j'utilise

^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

qui est celui utilisé dans ASP.NET par le régulateur de pression.

141
répondu Per Hornshøj-Schierbeck 2014-10-27 23:32:59

Ne savent pas à propos de les meilleures, mais celui-ci est au moins correct, tant que les adresses ont leurs commentaires dépouillé et remplacés par des espaces.

sérieusement. Vous devez utiliser une bibliothèque déjà écrite pour valider les e-mails. La meilleure façon est probablement d'envoyer un e-mail de vérification à cette adresse.

137
répondu Christian Vest Hansen 2009-03-21 21:19:05

les adresses email que je veux valider vont être utilisées par un ASP.NET application web utilisant le système.Net.Mail namespace pour envoyer des e-mails à une liste de personnes. Donc, plutôt que d'utiliser une expression régulière très complexe, j'essaie de créer une instance MailAddress à partir de l'adresse. Le mailaddress construtor fera une exception si l'adresse n'est pas correctement formée. Comme ça, je sais que je peux au moins retirer l'email de la porte. Bien sûr, c'est une validation côté serveur, mais à un minimum que vous avez besoin de cela de toute façon.

protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
    try
    {
        var a = new MailAddress(txtEmail.Text);
    }
    catch (Exception ex)
    {
        args.IsValid = false;
        emailValidator.ErrorMessage = "email: " + ex.Message;
    }
}
105
répondu davcar 2009-01-02 15:29:28

réponse Rapide

utiliser le regex suivant pour la validation des entrées:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+

adresses correspondant à ce regex:

  • ont une partie locale (C.-à-d. la partie avant le signe@) qui est strictement conforme à la RFC 5321/5322,
  • ont une partie de domaine (c.-à-d. la partie après le signe@ -) qui est un nom d'hôte avec au moins deux étiquettes, dont chacune est la plupart des 63 caractères.

la deuxième contrainte est une restriction à la RFC 5321/5322.

réponse élaborée

L'utilisation d'une expression régulière qui reconnaît les adresses e-mail pourrait être utile dans diverses situations: par exemple pour rechercher des adresses e-mail dans un document, pour valider les entrées de l'utilisateur, ou comme une contrainte d'intégrité sur un dépôt de données.

Il convient toutefois de noter que si vous vous voulez savoir si l'adresse se réfère à une boîte aux lettres existante, il n'y a pas de substitut pour envoyer un message à l'adresse. Si vous voulez seulement vérifier si une adresse est grammaticalement correcte, vous pouvez utiliser une expression régulière, mais notez que ""@[] est une adresse email grammaticalement correcte qui ne se réfère certainement pas à une boîte aux lettres existante.

la syntaxe des adresses e-mail a été définie dans divers RFC , notamment RFC 822 et RFC 5322 . La RFC 822 doit être considérée comme la norme "originale" et la RFC 5322 comme la dernière. La syntaxe définie dans la RFC 822 est la plus clémente et les normes subséquentes ont restreint la syntaxe de plus en plus loin, où les nouveaux systèmes ou services devraient reconnaître la syntaxe désuète, mais ne jamais la produire.

dans cette réponse, je vais prendre "adresse e-mail" pour signifier addr-spec tel que défini dans les RFC (i.e. jdoe@example.org , mais pas "John Doe"<jdoe@example.org> , ni some-group:jdoe@example.org,mrx@exampel.org; ).

il y a un problème avec la traduction des syntaxes RFC en regexes: les syntaxes ne sont pas régulières! C'est parce qu'ils permettent des commentaires optionnels dans les adresses e-mail qui peuvent être imbriquées à l'infini, alors que le nichage infini ne peut pas être décrit par une expression régulière. Pour rechercher ou valider des adresses contenant des commentaires, vous avez besoin d'un analyseur ou d'expressions plus puissantes. (Notez que les langues comme Perl ont des constructions pour décrire des grammaires hors contexte dans un regex. Dans cette réponse, Je ne tiendrai pas compte des commentaires et ne considérerai que les expressions régulières appropriées.

les RFC définissent les syntaxes pour les messages électroniques, pas pour les adresses électroniques en tant que telles. Les adresses peuvent apparaître dans divers champs d'en-tête et c'est là qu'elles sont principalement définies. Lorsqu'elles apparaissent dans les champs d'en-tête, les adresses peuvent contenir (entre des jetons lexicaux) des espaces, des commentaires et même des linebreaks. Sémantiquement cela n'a pas d' signification toutefois. En enlevant cet espace blanc, etc. d'une adresse vous obtenez un équivalent sémantique représentation canonique . Ainsi, la représentation canonique de first. last (comment) @ [3.5.7.9] est first.last@[3.5.7.9] .

différents syntaxes doivent être utilisés à des fins différentes. Si vous souhaitez rechercher des adresses e-mail dans un document (peut-être très ancien), il peut être judicieux d'utiliser la syntaxe définie dans la RFC 822. D'autre part, si vous souhaitez valider entrée de l'utilisateur vous pouvez utiliser la syntaxe définie dans la RFC 5322, n'acceptant probablement que les représentations canoniques. Vous devez décider quelle syntaxe s'applique à votre cas spécifique.

j'utilise les expressions régulières étendues de POSIX dans cette réponse, en supposant un jeu de caractères compatible ASCII.

RFC 822

je suis arrivé à l'expression régulière suivante. J'invite tout le monde à essayer de la briser. Si vous trouvez des faux positifs ou les faux négatifs, veuillez les poster dans un commentaire et je vais essayer de corriger l'expression dès que possible.

([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]))*(\\r)*")(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]))*(\\r)*"))*@([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]))*(\\r)*])(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]))*(\\r)*]))*

je crois qu'il est entièrement conforme à la RFC 822 incluant le errata . Il ne reconnaît les adresses électroniques que sous leur forme canonique. Pour un regex qui reconnaît les espaces (pliants) voir la dérivation ci-dessous.

La dérivation montre comment je suis arrivé à l'expression. J'ai la liste de tous les les règles grammaticales pertinentes du RFC exactement telles qu'elles apparaissent, suivies du regex correspondant. Lorsqu'un erratum a été publié, je donne une expression distincte pour la règle de grammaire corrigée (marquée "erratum") et j'utilise la version mise à jour comme sous-expression dans les expressions régulières subséquentes.

, Comme indiqué au paragraphe 3.1.4. de RFC 822 un espace blanc linéaire optionnel peut être inséré entre les jetons lexicaux. Le cas échéant, j'ai élargi les expressions pour tenir compte cette règle, et marqué avec "opt-lwsp".

CHAR        =  <any ASCII character>
            =~ .

CTL         =  <any ASCII control character and DEL>
            =~ [\x00-\x1F\x7F]

CR          =  <ASCII CR, carriage return>
            =~ \r

LF          =  <ASCII LF, linefeed>
            =~ \n

SPACE       =  <ASCII SP, space>
            =~  

HTAB        =  <ASCII HT, horizontal-tab>
            =~ \t

<">         =  <ASCII quote mark>
            =~ "

CRLF        =  CR LF
            =~ \r\n

LWSP-char   =  SPACE / HTAB
            =~ [ \t]

linear-white-space =  1*([CRLF] LWSP-char)
                   =~ ((\r\n)?[ \t])+

specials    =  "(" / ")" / "<" / ">" / "@" /  "," / ";" / ":" / "\" / <"> /  "." / "[" / "]"
            =~ [][()<>@,;:\".]

quoted-pair =  "\" CHAR
            =~ \.

qtext       =  <any CHAR excepting <">, "\" & CR, and including linear-white-space>
            =~ [^"\\r]|((\r\n)?[ \t])+

dtext       =  <any CHAR excluding "[", "]", "\" & CR, & including linear-white-space>
            =~ [^][\\r]|((\r\n)?[ \t])+

quoted-string  =  <"> *(qtext|quoted-pair) <">
               =~ "([^"\\r]|((\r\n)?[ \t])|\.)*"
(erratum)      =~ "(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*"

domain-literal =  "[" *(dtext|quoted-pair) "]"
               =~ \[([^][\\r]|((\r\n)?[ \t])|\.)*]
(erratum)      =~ \[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*]

atom        =  1*<any CHAR except specials, SPACE and CTLs>
            =~ [^][()<>@,;:\". \x00-\x1F\x7F]+

word        =  atom / quoted-string
            =~ [^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*"

domain-ref  =  atom

sub-domain  =  domain-ref / domain-literal
            =~ [^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*]

local-part  =  word *("." word)
            =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*")(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*"))*
(opt-lwsp)  =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*")(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*"))*

domain      =  sub-domain *("." sub-domain)
            =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*])(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*]))*

addr-spec   =  local-part "@" domain
            =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*")(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*"))*@([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*])(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*]))*
(opt-lwsp)  =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*")((\r\n)?[ \t])*(\.((\r\n)?[ \t])*([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*")((\r\n)?[ \t])*)*@((\r\n)?[ \t])*([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*])(((\r\n)?[ \t])*\.((\r\n)?[ \t])*([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]|(\r\n)?[ \t]))*(\\r)*]))*
(canonical) =~ ([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]))*(\\r)*")(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|"(\n|(\\r)*([^"\\r\n]|\[^\r]))*(\\r)*"))*@([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]))*(\\r)*])(\.([^][()<>@,;:\". \x00-\x1F\x7F]+|\[(\n|(\\r)*([^][\\r\n]|\[^\r]))*(\\r)*]))*

RFC 5322

je suis arrivé à l'expression régulière suivante. J'invite tout le monde à essayer de la briser. Si vous trouvez des faux positifs ou de faux négatifs, veuillez les poster dans un commentaire et je vais essayer de corriger l'expression dès que possible.

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

je crois qu'il est entièrement conforme à la RFC 5322 y compris le errata . Il ne reconnaît les adresses électroniques que sous leur forme canonique. Pour un regex qui reconnaît les espaces (pliants) voir la dérivation ci-dessous.

La dérivation montre comment je suis arrivé à l'expression. J'énumère toutes les règles grammaticales pertinentes du RFC exactement telles qu'elles apparaissent, suivies du regex correspondant. Pour les règles qui comprennent sémantiquement hors de propos (pliant) espace blanc, je donne un regex séparé marqué "(normalisé) " qui ne accepter cet espace.

j'ai ignoré toutes les règles" obs - " du RFC. Cela signifie que les regexes ne correspondent qu'à des adresses email strictement conformes à la RFC 5322. Si vous devez faire correspondre les "anciennes" adresses (comme le fait la grammaire plus lâche incluant les règles "obs -"), vous pouvez utiliser l'une des regexes RFC 822 du paragraphe précédent.

VCHAR           =   %x21-7E
                =~  [!-~]

ALPHA           =   %x41-5A / %x61-7A
                =~  [A-Za-z]

DIGIT           =   %x30-39
                =~  [0-9]

HTAB            =   %x09
                =~  \t

CR              =   %x0D
                =~  \r

LF              =   %x0A
                =~  \n

SP              =   %x20
                =~  

DQUOTE          =   %x22
                =~  "

CRLF            =   CR LF
                =~  \r\n

WSP             =   SP / HTAB
                =~  [\t ]

quoted-pair     =   "\" (VCHAR / WSP)
                =~  \[\t -~]

FWS             =   ([*WSP CRLF] 1*WSP)
                =~  ([\t ]*\r\n)?[\t ]+

ctext           =   %d33-39 / %d42-91 / %d93-126
                =~  []!-'*-[^-~]

("comment" is left out in the regex)
ccontent        =   ctext / quoted-pair / comment
                =~  []!-'*-[^-~]|(\[\t -~])

(not regular)
comment         =   "(" *([FWS] ccontent) [FWS] ")"

(is equivalent to FWS when leaving out comments)
CFWS            =   (1*([FWS] comment) [FWS]) / FWS
                =~  ([\t ]*\r\n)?[\t ]+

atext           =   ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
                =~  [-!#-'*+/-9=?A-Z^-~]

dot-atom-text   =   1*atext *("." 1*atext)
                =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*

dot-atom        =   [CFWS] dot-atom-text [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*

qtext           =   %d33 / %d35-91 / %d93-126
                =~  []!#-[^-~]

qcontent        =   qtext / quoted-pair
                =~  []!#-[^-~]|(\[\t -~])

(erratum)
quoted-string   =   [CFWS] DQUOTE ((1*([FWS] qcontent) [FWS]) / FWS) DQUOTE [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  "([]!#-[^-~ \t]|(\[\t -~]))+"

dtext           =   %d33-90 / %d94-126
                =~  [!-Z^-~]

domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
                =~  (([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  \[[\t -Z^-~]*]

local-part      =   dot-atom / quoted-string
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+"

domain          =   dot-atom / domain-literal
                =~  (([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?
(normalized)    =~  [-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*]

addr-spec       =   local-part "@" domain
                =~  ((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?)@((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?)
(normalized)    =~  ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

notez que certaines sources (notamment w3c ) affirment que la RFC 5322 est trop stricte sur la partie locale (c'est à dire la partie avant le signe@). C'est parce que "..", "un..b" et "a". pas valide dot-atomes, alors qu'ils peuvent être utilisés comme noms de boîtes aux lettres. Le RFC, cependant, ne tenir compte des parties locales comme celles-ci, sauf qu'ils doivent être cités. Donc au lieu de a..b@example.net vous devez écrire "a..b"@example.net , ce qui est sémantiquement équivalent.

autres restrictions

SMTP (tel que défini à RFC 5321 ) restreint davantage l'ensemble des adresses de courriel valides (ou en fait: les noms de boîtes aux lettres). Il semble raisonnable d'imposer cette grammaire plus stricte, de sorte que l'adresse e-mail correspondante puisse effectivement être utilisée pour envoyer un e-mail.

RFC 5321 laisse essentiellement seule la partie" locale " (c'est-à-dire la partie avant le signe@), mais est plus stricte sur la partie de domaine (c'est-à-dire la partie après le signe@). Il ne permet que les noms d'hôtes à la place des points-atomes et adresse littérales en place du domaine de littéraux.

la grammaire présentée dans la RFC 5321 est trop clémente en ce qui concerne les noms d'hôtes et les adresses IP. J'ai pris la liberté de "corriger" les règles en question, en utilisant ce projet et RFC 1034 comme lignes directrices. Voici la regex résultante.

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])

Note que, selon le cas d'utilisation, vous ne voulez pas permettre une "Général-adresse-littérale" dans votre regex. Notez également que j'ai utilisé un lookahead négatif (?!IPv6:) dans la version finale de regex pour empêcher la partie" General-address-literal " de correspondre à des adresses IPv6 mal formées. Certains processeurs regex ne supportent pas les lookahead négatifs. Supprimer la sous-couche |(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+ de la regex si vous voulez supprimer toute la partie" General-address-literal".

Voici la dérivation:

Let-dig         =   ALPHA / DIGIT
                =~  [0-9A-Za-z]

Ldh-str         =   *( ALPHA / DIGIT / "-" ) Let-dig
                =~  [0-9A-Za-z-]*[0-9A-Za-z]

(regex is updated to make sure sub-domains are max. 63 charactes long - RFC 1034 section 3.5)
sub-domain      =   Let-dig [Ldh-str]
                =~  [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?

Domain          =   sub-domain *("." sub-domain)
                =~  [0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*

Snum            =   1*3DIGIT
                =~  [0-9]{1,3}

(suggested replacement for "Snum")
ip4-octet       =   DIGIT / %x31-39 DIGIT / "1" 2DIGIT / "2" %x30-34 DIGIT / "25" %x30-35
                =~  25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]

IPv4-address-literal    =   Snum 3("."  Snum)
                        =~  [0-9]{1,3}(\.[0-9]{1,3}){3}

(suggested replacement for "IPv4-address-literal")
ip4-address     =   ip4-octet 3("." ip4-octet)
                =~  (25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}

(suggested replacement for "IPv6-hex")
ip6-h16         =   "0" / ( (%x49-57 / %x65-70 /%x97-102) 0*3(%x48-57 / %x65-70 /%x97-102) )
                =~  0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}

(not from RFC)
ls32            =   ip6-h16 ":" ip6-h16 / ip4-address
                =~  (0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}

(suggested replacement of "IPv6-addr")
ip6-address     =                                      6(ip6-h16 ":") ls32
                    /                             "::" 5(ip6-h16 ":") ls32
                    / [                 ip6-h16 ] "::" 4(ip6-h16 ":") ls32
                    / [ *1(ip6-h16 ":") ip6-h16 ] "::" 3(ip6-h16 ":") ls32
                    / [ *2(ip6-h16 ":") ip6-h16 ] "::" 2(ip6-h16 ":") ls32
                    / [ *3(ip6-h16 ":") ip6-h16 ] "::"   ip6-h16 ":"  ls32
                    / [ *4(ip6-h16 ":") ip6-h16 ] "::"                ls32
                    / [ *5(ip6-h16 ":") ip6-h16 ] "::"   ip6-h16
                    / [ *6(ip6-h16 ":") ip6-h16 ] "::"
                =~  (((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::

IPv6-address-literal    =   "IPv6:" ip6-address
                        =~  IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)

Standardized-tag        =   Ldh-str
                        =~  [0-9A-Za-z-]*[0-9A-Za-z]

dcontent        =   %d33-90 / %d94-126
                =~  [!-Z^-~]

General-address-literal =   Standardized-tag ":" 1*dcontent
                        =~  [0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+

address-literal =   "[" ( IPv4-address-literal / IPv6-address-literal / General-address-literal ) "]"
                =~  \[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)]

Mailbox         =   Local-part "@" ( Domain / address-literal )
                =~  ([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])

validation des entrées de L'utilisateur

un cas d'usage courant est la validation des entrées de l'utilisateur, par exemple sur un formulaire html. Dans ce cas, il est généralement raisonnable d'exclure adresses-littérales et d'exiger au moins deux étiquettes dans le nom d'hôte. En prenant comme base le regex amélioré RFC 5321 de la section précédente, l'expression résultante serait:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+

Je ne recommande pas de restreindre davantage la partie locale, par exemple en excluant les chaînes citées, puisque nous Je ne sais pas quel type de noms de boîte mail certains hôtes permettent (comme "a..b"@example.net ou même "a b"@example.net ).

Je ne recommande pas non plus de valider explicitement contre une liste de domaines littéraux de premier niveau ou même d'imposer des contraintes de longueur (rappelez-vous comment ".Musée "invalidé [a-z]{2,4} ), mais si vous devez:

([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info| etc... )

assurez-vous de garder votre regex à jour si vous décider de suivre la voie de la validation de domaine explicite de haut niveau.

autres considérations

Lorsqu'ils n'acceptent que les noms d'hôtes dans la partie domaine (après le signe@ -), les regexes ci-dessus n'acceptent que les étiquettes avec au plus 63 caractères, comme ils devraient. Cependant, ils n'imposent pas le fait que le nom d'hôte entier doit avoir au plus 253 caractères (y compris les points). Bien que cette contrainte soit à proprement parler encore régulière, elle n'est pas possibilité de créer une regex qui incorpore cette règle.

une autre considération, en particulier lors de l'utilisation des regexes pour la validation des entrées, est la rétroaction à l'utilisateur. Si un utilisateur entre une adresse incorrecte, il serait bon de donner un peu plus de feedback qu'une simple "adresse incorrecte sur le plan syntaxique". Avec "vanille" regexes ce n'est pas possible.

ces deux considérations pourraient être abordées en analysant l'adresse. La contrainte de longueur supplémentaire sur dans certains cas, les noms d'hôtes peuvent aussi être adressés en utilisant un regex supplémentaire qui le vérifie, et en faisant correspondre l'adresse avec les deux expressions.

aucun des regexes dans cette réponse ne sont optimisés pour la performance. Si la performance est un problème, vous devriez voir si (et comment) l'expression rationnelle de votre choix peut être optimisé.

97
répondu Rinke 2016-05-02 22:42:11

Il ya beaucoup d'exemples de ce sur le net (et je pense même un qui valide pleinement la RFC - mais il est des dizaines/centaines de lignes de long si la mémoire sert). Les gens ont tendance à se laisser emporter valider ce genre de chose. Pourquoi ne pas simplement vérifier qu'il a un @ et au moins un . et répond à une longueur minimale simple. Il est trivial d'entrer un faux e-mail et toujours correspondre à n'importe quel regex valide de toute façon. Je suppose que les faux positifs sont mieux que des faux négatifs.

70
répondu Draemon 2008-10-14 14:18:58

en décidant quels personnages sont autorisés, rappelez-vous s'il vous plaît vos amis apostrophes et avec un trait d'Union. Je n'ai aucun contrôle sur le fait que mon entreprise génère mon adresse e-mail en utilisant mon nom du système RH. Cela inclut l'apostrophe de mon nom de famille. Je ne peux pas vous dire combien de fois j'ai été empêché d'interagir avec un site Web par le fait que mon adresse e-mail est "invalide".

61
répondu DOK 2008-10-14 16:19:04

Cette expression est à partir de Perl e-Mail::Valide de la bibliothèque. Je pense que c'est le plus précis, il correspond aux 822. Et, il est basé sur l'expression régulière dans le livre D'O'Reilly:

Expression régulière construite en utilisant L'exemple de Jeffrey Friedl dans Mastering Regular Expressions ( http://www.ora.com/catalog/regexp / ).

$RFC822PAT = <<'EOF';
[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\
xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xf
f\n5()]*)*\)[0\t]*)*(?:(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\x
ff]+(?![^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff])|"[^\\x80-\xff\n5
"]*(?:\[^\x80-\xff][^\\x80-\xff\n5"]*)*")[0\t]*(?:\([^\\x80-\
xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80
-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*
)*(?:\.[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\
\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\
x80-\xff\n5()]*)*\)[0\t]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x8
0-\xff]+(?![^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff])|"[^\\x80-\xff\n
5"]*(?:\[^\x80-\xff][^\\x80-\xff\n5"]*)*")[0\t]*(?:\([^\\x
80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^
\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0
\t]*)*)*@[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([
^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\
\x80-\xff\n5()]*)*\)[0\t]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\
x80-\xff]+(?![^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-
\xff\n5\[\]]|\[^\x80-\xff])*\])[0\t]*(?:\([^\\x80-\xff\n5()
]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\
x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*(?:\.[
0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\
n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n\
015()]*)*\)[0\t]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?!
[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-\xff\n5\[\
]]|\[^\x80-\xff])*\])[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\
x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n
5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*)*|(?:[^(0)<>@,;:".
\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]
)|"[^\\x80-\xff\n5"]*(?:\[^\x80-\xff][^\\x80-\xff\n5"]*)*")[^
()<>@,;:".\\[\]\x80-\xff"151900920"0-02-7]*(?:(?:\([^\\x80-\xff\n"151900920"
15()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][
^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)|"[^\\x80-\xff\
n5"]*(?:\[^\x80-\xff][^\\x80-\xff\n5"]*)*")[^()<>@,;:".\\[\]\
x80-\xff"151900920"0-02-7]*)*<[0\t]*(?:\([^\\x80-\xff\n5()]*(?
:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-
\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*(?:@[0\t]*
(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5
()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()
]*)*\)[0\t]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^("151900920"
40)<>@,;:".\\[\]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-\xff\n5\[\]]|\
[^\x80-\xff])*\])[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\
xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*
)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*(?:\.[0\t]*(?:\([^\\x80
-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x
80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t
]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".\
\[\]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-\xff\n5\[\]]|\[^\x80-\xff])
*\])[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x
80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80
-\xff\n5()]*)*\)[0\t]*)*)*(?:,[0\t]*(?:\([^\\x80-\xff\n5(
)]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\
\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*@[0\t
]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n"151900920"
15()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5
()]*)*\)[0\t]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(
0)<>@,;:".\\[\]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-\xff\n5\[\]]|
\[^\x80-\xff])*\])[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80
-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()
]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*(?:\.[0\t]*(?:\([^\\x
80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^
\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0
\t]*)*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".
\\[\]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-\xff\n5\[\]]|\[^\x80-\xff
])*\])[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\
\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x
80-\xff\n5()]*)*\)[0\t]*)*)*)*:[0\t]*(?:\([^\\x80-\xff\n5
()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\
\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*)?(?:[^
(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".\\[\]"151900920"0-
7\x80-\xff])|"[^\\x80-\xff\n5"]*(?:\[^\x80-\xff][^\\x80-\xff\
n5"]*)*")[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|
\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))
[^\\x80-\xff\n5()]*)*\)[0\t]*)*(?:\.[0\t]*(?:\([^\\x80-\xff
\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\x
ff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*(
?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".\\[\]\
000-7\x80-\xff])|"[^\\x80-\xff\n5"]*(?:\[^\x80-\xff][^\\x80-\
xff\n5"]*)*")[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\x
ff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)
*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*)*@[0\t]*(?:\([^\\x80-\x
ff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-
\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)
*(?:[^(0)<>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".\\[\
]"151900920"0-7\x80-\xff])|\[(?:[^\\x80-\xff\n5\[\]]|\[^\x80-\xff])*\]
)[0\t]*(?:\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-
\xff\n5()]*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\x
ff\n5()]*)*\)[0\t]*)*(?:\.[0\t]*(?:\([^\\x80-\xff\n5()]*(
?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]*(?:\[^\x80-\xff][^\\x80
-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)*\)[0\t]*)*(?:[^(0)<
>@,;:".\\[\]"151900920"0-7\x80-\xff]+(?![^(0)<>@,;:".\\[\]"151900920"0-7\x8
0-\xff])|\[(?:[^\\x80-\xff\n5\[\]]|\[^\x80-\xff])*\])[0\t]*(?:
\([^\\x80-\xff\n5()]*(?:(?:\[^\x80-\xff]|\([^\\x80-\xff\n5()]
*(?:\[^\x80-\xff][^\\x80-\xff\n5()]*)*\))[^\\x80-\xff\n5()]*)
*\)[0\t]*)*)*>)
EOF
61
répondu Evan Carroll 2015-11-22 03:54:06

pendant que vous écrivez en PHP, je vous conseille D'utiliser la validation PHP pour les e-mails.

filter_var($value, FILTER_VALIDATE_EMAIL)

si vous utilisez une version php inférieure à 5.3.6 veuillez prendre note de ce problème: https://bugs.php.net/bug.php?id=53091

si vous voulez plus d'informations sur le fonctionnement de cette validation buid-in, voir ici: est-ce que filter_var FILTER_VALIDATE_EMAIL de PHP fonctionne réellement?

44
répondu SimonSimCity 2017-05-23 11:47:34

Cal Henderson (Flickr) a écrit un article intitulé Parsing Email addresses in PHP et montre comment faire correctement RFC (2)822-compatible email Address parsing. Vous pouvez également obtenir le code source dans php , python et ruby qui est CC licensed .

42
répondu adnam 2008-10-14 16:35:44

Je ne prends jamais la peine de créer avec ma propre expression régulière, parce que les chances sont que quelqu'un d'autre a déjà trouvé une meilleure version. J'utilise toujours regexlib pour en trouver un à mon goût.

41
répondu Kon 2008-10-14 14:23:11

il n'y en a pas un qui soit vraiment utilisable.

Je discute de quelques problèmes dans ma réponse à y a-t-il une bibliothèque php pour la validation des adresses e-mail? , il est discuté aussi dans reconnaissance Regexp de l'adresse e-mail dur?

bref, ne vous attendez pas à ce qu'un seul regex utilisable fasse un bon travail. Et le meilleur regex validera la syntaxe, pas la validité d'un e-mail (jhohn@example.com est correct mais il sera probablement rebondir...).

37
répondu PhiLho 2017-05-23 11:55:13

une simple expression régulière qui ne rejetterait pas au moins une adresse email valide serait de vérifier quelque chose, suivi d'un @ sign et puis quelque chose suivi d'une période et au moins 2 quelque chose. Il ne rejettera rien, mais après avoir examiné la spécification, Je ne peux pas trouver d'e-mail qui serait valide et rejeté.

email = ~ /.+@[^@]+\.[^@]{2,}$/

33
répondu spig 2013-03-07 19:57:59

vous pouvez utiliser celui employé par le plugin de Validation de jQuery:

/^((([a-z]|\d|[!#$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i
29
répondu chaos 2009-05-23 18:22:34

Pour l'évaluation la plus complète de la meilleure expression régulière pour valider une adresse e-mail veuillez consulter ce lien; " la Comparaison de l'E-mail de la Validation des Expressions Régulières "

Voici l'expression courante en haut à des fins de référence:

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i
24
répondu Eric Schoonover 2010-05-28 22:03:55

sans oublier que les noms de domaine non latins (chinois, arabe, grec, hébreu, Cyrillique, etc.) seront autorisés dans le dans un avenir proche . Tout le monde doit changer l'email regex utilisé, parce que ces caractères ne doivent sûrement pas être couverts par [a-z]/i ou \w . Ils seront vouées à l'échec.

après tout ,le meilleur façon de valider l'adresse e-mail est encore à effectivement envoyer un e-mail à l'adresse en question pour valider l'adresse. Si l'adresse électronique est la partie de l'authentification de l'utilisateur (inscription/connexion/etc...), vous pouvez parfaitement combiner avec l'activation par l'utilisateur du système. I. e. envoyer un e-mail avec un lien avec une unique clé d'activation à l'adresse e-mail spécifiée et d'autoriser uniquement la connexion lorsque l'utilisateur a activé le compte nouvellement créé en utilisant le lien dans l'e-mail.

si le but de la regex est juste d'informer rapidement l'utilisateur dans L'UI que l'adresse e-mail spécifiée ne ressemble pas au bon format, best est encore de vérifier si elle correspond fondamentalement au regex suivant:

^([^.@]+)(\.[^.@]+)*@([^.@]+\.)+([^.@]+)$

C'est aussi Simple que ça. Pourquoi diable vous souciez-vous des caractères utilisés dans le nom et le domaine? C'est la responsabilité du client d'entrer une adresse email valide, pas celle du serveur. Même si le client entre une syntaxiquement adresse e-mail valide comme aa@bb.cc , cela ne garantit pas que c'est une pièce de théâtre adresse e-mail. Personne ne peut couvrir ça.

22
répondu BalusC 2009-12-18 23:40:35

le HTML5 Spec suggère un simple regex pour valider les adresses email:

/^[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])?)*$/

cela ne respecte pas intentionnellement RFC 5322 .

Note: cette exigence est une violation volontaire de RFC 5322 , qui définit une syntaxe pour les adresses e-mail qui est simultanément trop stricte (avant le caractère @ ), trop vague (après le caractère @ ), et trop laxiste (permettant des commentaires, des caractères d'espace, et des cordes citées dans des manières inconnues de la plupart des utilisateurs) pour être d'usage pratique ici.

la longueur totale pourrait aussi être limitée à 254 caractères, par RFC 3696 errata 1690 .

16
répondu Ross Allan 2018-03-21 12:53:10

pour une démonstration vivante, le monstre suivant est assez bon mais ne reconnaît toujours pas correctement toutes les adresses email syntaxiquement valides: il reconnaît les commentaires imbriqués jusqu'à quatre niveaux de profondeur.

c'est un travail pour un analyseur, mais même si une adresse est valide syntaxiquement, elle peut ne pas être livrable. Parfois, il faut recourir à la méthode du péquenaud:"

// derivative of work with the following copyright and license:
// Copyright (c) 2004 Casey West.  All rights reserved.
// This module is free software; you can redistribute it and/or
// modify it under the same terms as Perl itself.

// see http://search.cpan.org/~cwest/Email-Address-1.80/

private static string gibberish = @"
(?-xism:(?:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))
|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))
|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x
0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<DQ>(?-xism:(?-xism:[
^\<DQ>])|(?-xism:\(?-xism:[^\x0A\x0D])))+<DQ>(?-xism:(?-xi
sm:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xis
m:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\
s*)+|\s+)*))+)?(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?
-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[
^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<(?-xism:(?-xi
sm:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^(
)\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(
?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))
|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<
>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]
+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))
|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:
(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s
*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x
0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xi
sm:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*
<DQ>(?-xism:(?-xism:[^\<DQ>])|(?-xism:\(?-xism:[^\x0A\x0D]
)))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-x
ism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+
)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:(
?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?
-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s
*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(
?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[
^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+)
)|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)
+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\
x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-x
ism:[^\[\]\])|(?-xism:\(?-xism:[^\x0A\x0D])))+)*\s*\](?-xi
sm:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:
\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+
)*\s*\)\s*)+|\s+)*)))>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-
xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^
\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))|(?-xism:(?-x
ism:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*
(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D])
)|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()
<>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s
]+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+)
)|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism
:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\
s*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\
x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-x
ism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)
*<DQ>(?-xism:(?-xism:[^\<DQ>])|(?-xism:\(?-xism:[^\x0A\x0D
])))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-
xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)
+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:
(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(
?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[
^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\
s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+
(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism
:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:
[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+
))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*
)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism
:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\(
(?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A
\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-
xism:[^\[\]\])|(?-xism:\(?-xism:[^\x0A\x0D])))+)*\s*\](?-x
ism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism
:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))
+)*\s*\)\s*)+|\s+)*))))(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?
>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:
\s*(?-xism:(?-xism:(?>[^()\]+))|(?-xism:\(?-xism:[^\x0A\x0
D]))|)+)*\s*\)\s*))+)*\s*\)\s*)*)"
  .Replace("<DQ>", "\"")
  .Replace("\t", "")
  .Replace(" ", "")
  .Replace("\r", "")
  .Replace("\n", "");

private static Regex mailbox =
  new Regex(gibberish, RegexOptions.ExplicitCapture); 
14
répondu Greg Bacon 2009-06-25 15:15:07

voici le PHP que j'utilise. J'ai choisi cette solution dans l'esprit de "les faux positifs sont meilleurs que les faux négatifs" comme l'a déclaré un autre commentateur ici et en ce qui concerne le maintien de votre temps de réponse et la charge du serveur vers le bas ... il n'y a vraiment pas besoin de gaspiller les ressources du serveur avec une expression régulière quand cela éliminera la plupart des erreurs utilisateur simples. Vous pouvez toujours suivre cela en envoyant un email de test si vous voulez.

function validateEmail($email) {
  return (bool) stripos($email,'@');
}
11
répondu Mac 2011-07-20 03:37:42

Selon la norme officielle RFC 2822 e-mail valide regex est

(?:[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])+)\])

si vous voulez l'utiliser en Java son vraiment très facile

import java.util.regex.*;

class regexSample 
{
   public static void main(String args[]) 
   {
      //Input the string for validation
      String email = "xyz@hotmail.com";

      //Set the email pattern string
      Pattern p = Pattern.compile(" (?:[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])+)\]");

      //Match the given string with the pattern
      Matcher m = p.matcher(email);

      //check whether match is found 
      boolean matchFound = m.matches();

      if (matchFound)
        System.out.println("Valid Email Id.");
      else
        System.out.println("Invalid Email Id.");
   }
}
11
répondu AZ_ 2012-01-23 19:35:54

RFC 5322 standard:

permet une partie locale, une partie locale à chaîne de caractères, une partie locale obsolète (mélange d'atomes de points et de chaîne de caractères), une partie locale, un domaine de nom de domaine, (adresse IPv4, IPv6 et IPv4-mapped IPv6) un domaine littéral et (imbriqué) un CFWS.

'/^(?!(?>(?1)"?(?>\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD'

RFC 5321 standard:

Permet dot-atome local-part, quoted-string local-partie, domaine, nom de domaine, et (IPv4, IPv6 et IPv4 mappée adresse IPv6) domaine littéral domaine.

'/^(?!(?>"?(?>\\[ -~]|[^"])"?){255,})(?!"?(?>\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?6)){3}))\])$/iD'

de Base":

permet d'utiliser des noms de domaine et des parties locales de noms de domaine dot-atom (nécessitant au moins deux étiquettes de noms de domaine avec le TLD limité à 2-6 caractères alphabétiques).

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"
11
répondu MichaelRushton 2012-12-19 12:17:26

étrange que vous "ne pouvez pas" autoriser les TLD à 4 caractères. Vous bannissez les gens de .info et .nom , et l'arrêt de limitation de longueur .voyages et .Musée , mais oui, ils sont moins communs que les TLD de 2 caractères et les TLD de 3 caractères.

vous devriez autoriser les alphabets en majuscules aussi. Les systèmes de courrier électronique normaliseront la partie locale et la partie domaine.

pour votre regex de la partie Domaine, Le nom de domaine ne peut pas commencer par '-' et ne peut pas se terminer par '-'. Dash ne peut rester qu'entre les deux.

si vous avez utilisé la bibliothèque PEAR, vérifiez leur fonction mail (oublié le nom exact/bibliothèque). Vous pouvez valider l'adresse e-mail en appelant une fonction, et il valide l'adresse e-mail selon la définition dans RFC822.

8
répondu Joseph Yee 2008-11-06 04:48:18
public bool ValidateEmail(string sEmail)
{
    if (sEmail == null)
    {
        return false;
    }

    int nFirstAT = sEmail.IndexOf('@');
    int nLastAT = sEmail.LastIndexOf('@');

    if ((nFirstAT > 0) && (nLastAT == nFirstAT) && (nFirstAT < (sEmail.Length - 1)))
    {
        return (Regex.IsMatch(sEmail, @"^[a-z|0-9|A-Z]*([_][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*([.][a-z|0-9|A-Z]+)*(([_][a-z|0-9|A-Z]+)*)?@[a-z][a-z|0-9|A-Z]*\.([a-z][a-z|0-9|A-Z]*(\.[a-z][a-z|0-9|A-Z]*)?)$"));
    }
    else
    {
        return false;
    }
}
8
répondu Murthy Jeedigunta 2011-08-02 13:11:34