Au fil des ans, j'ai lentement développé une expression régulière qui valide correctement la plupart des adresses e-mail, en supposant qu'elles n'utilisent pas d'adresse IP comme partie serveur.
Je l'utilise dans plusieurs programmes PHP, et cela fonctionne la plupart du temps. Cependant, de temps en temps, je suis contacté par quelqu'un qui a des problèmes avec un site qui l'utilise, et je dois finir par faire quelques ajustements (plus récemment, j'ai réalisé que je n'autorisais pas les TLD à 4 caractères).
Quelle est la meilleure expression régulière que vous avez ou avez vue pour valider les e-mails?
J'ai vu plusieurs solutions qui utilisent des fonctions qui utilisent plusieurs expressions plus courtes, mais je préfère avoir une longue expression complexe dans une fonction simple au lieu de plusieurs expressions courtes dans une fonction plus complexe.
Réponses:
Le regex entièrement conforme à la RFC 822 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 e-mail est la RFC 5322 . La RFC 5322 conduit à une expression régulière qui peut être comprise si elle est étudiée pendant quelques minutes et est suffisamment efficace pour une utilisation réelle.
Une expression régulière conforme à la RFC 5322 se trouve en haut de la page sur http://emailregex.com/ mais utilise le modèle d'adresse IP flottant sur Internet avec un bogue qui autorise
00
toutes les valeurs décimales d'octets non signés dans un adresse délimitée par des points, ce qui est illégal. Le reste semble cohérent avec la grammaire RFC 5322 et passe plusieurs tests en utilisantgrep -Po
, y compris les cas, les noms de domaine, les adresses IP, les mauvais et les noms de compte avec et sans guillemets.En corrigeant le
00
bogue dans le modèle IP, nous obtenons un regex fonctionnel et assez rapide. (Grattez la version rendue, pas la démarque, pour le code réel.)ou:
Voici le schéma de la machine à états finis pour l'expression rationnelle ci-dessus qui est plus claire que l'expression rationnelle elle-même
Les modèles plus sophistiqués en Perl et PCRE (bibliothèque d'expression régulière utilisée par exemple en PHP) peuvent correctement analyser RFC 5322 sans accroc . Python et C # peuvent également le faire, mais ils utilisent une syntaxe différente de celles des deux premiers. Cependant, si vous êtes obligé d'utiliser l'un des nombreux langages de correspondance de modèles moins puissants, il est préférable d'utiliser un véritable analyseur.
Il est également important de comprendre que sa validation par le RFC ne vous dit absolument rien si cette adresse existe réellement sur le domaine fourni, ou si la personne qui saisit l'adresse est son véritable propriétaire. Les gens inscrivent les autres aux listes de diffusion de cette façon tout le temps. Correction qui nécessite un type de validation plus sophistiqué qui implique d'envoyer à cette adresse un message qui comprend un jeton de confirmation destiné à être entré sur la même page Web que l'adresse.
Les jetons de confirmation sont le seul moyen de savoir que vous avez obtenu l'adresse de la personne qui l'a saisie. C'est pourquoi la plupart des listes de diffusion utilisent désormais ce mécanisme pour confirmer les inscriptions. Après tout, n'importe qui peut réprimer
[email protected]
, et cela sera même analysé comme légal, mais ce n'est probablement pas la personne à l'autre bout.Pour PHP, vous ne devez pas utiliser le modèle donné dans Valider une adresse e-mail avec PHP, la bonne façon dont je cite:
Ce n'est pas mieux que tous les autres modèles non RFC. Il n'est même pas assez intelligent pour gérer même le RFC 822 , encore moins le RFC 5322. Celui-ci cependant.
Si vous voulez devenir fantaisiste et pédant, implémentez 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 dire à quelqu'un que son adresse e-mail parfaitement valide n'est pas valide (un faux positif) parce que votre expression régulière ne peut pas la gérer est 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 les adresses électroniques qui seraient autrement considérées comme non valides car il démonte l'adresse électronique selon chaque RFC. Cela permet une expérience potentiellement plus agréable, comme
Voir aussi Validation des adresses e-mail , y compris les commentaires. Ou Comparaison d'adresses électroniques validant des expressions régulières .
Démo Debuggex
la source
Vous ne devez pas utiliser d'expressions régulières pour valider les adresses e-mail.
À la place, utilisez la classe MailAddress , comme ceci:
La
MailAddress
classe utilise un analyseur BNF pour valider l'adresse en totale conformité avec RFC822.Si vous envisagez d'utiliser le
MailAddress
pour valider l'adresse de messagerie, sachez que cette approche accepte également la partie nom complet de l'adresse de messagerie et que ce n'est peut-être pas exactement ce que vous souhaitez obtenir. Par exemple, il accepte ces chaînes comme adresses e-mail valides:Dans certains de ces cas, seule la dernière partie des chaînes est analysée en tant qu'adresse; le reste avant c'est le nom d'affichage. Pour obtenir une adresse e-mail standard sans aucun nom d'affichage, vous pouvez vérifier l'adresse normalisée par rapport à votre chaîne d'origine.
De plus, une adresse ayant un point à la fin, comme,
user@company.
est également acceptée par MailAddress.Si vous voulez vraiment utiliser une expression régulière, la voici :
la source
[email protected]
. Vous ne devez pas vous fier à la validation des e-mails pour empêcher XSS.Cette question est souvent posée, mais je pense que vous devriez prendre du recul et vous demander pourquoi vous souhaitez valider syntaxiquement les adresses e-mail? Quel est vraiment l'avantage?
Si vous souhaitez valider l'exactitude d'un e-mail, vous n'avez pas d'autre choix que d'envoyer un e-mail de confirmation et de demander à l'utilisateur d'y répondre. Dans de nombreux cas , vous devrez avoir à envoyer un mail de confirmation de toute façon pour des raisons de sécurité ou pour des raisons d' ordre éthique ( de sorte que vous ne pouvez pas quelqu'un signe par exemple à un service contre leur gré).
la source
me@hotmail
, il est évident qu'il ne recevra pas votre e-mail de confirmation, et où est-il? Ils ne sont plus sur votre site et se demandent pourquoi ils n'ont pas pu s'inscrire. En fait non, ils ne le sont pas - ils vous ont complètement oublié. Cependant, si vous pouviez simplement faire un test de santé mentale de base avec une expression régulière alors qu'ils sont toujours avec vous, alors ils peuvent détecter cette erreur immédiatement et vous avez un utilisateur heureux.[email protected]
adresses indiquent un commandant en chef très netbusy. :)Tout dépend de la précision que vous souhaitez avoir. Pour mes besoins, où j'essaie simplement de garder des choses comme
bob @ aol.com
(espaces dans les e-mails) ousteve
(pas de domaine du tout) oumary@aolcom
(pas de période avant .com), j'utiliseBien sûr, cela correspondra à des choses qui ne sont pas des adresses e-mail valides, mais il s'agit d'obtenir des erreurs simples courantes.
Il y a un certain nombre de changements qui peuvent être apportés à cette expression régulière (et certains sont dans les commentaires de cette réponse), mais c'est simple et facile à comprendre, et c'est une bonne première tentative.
la source
.
est inclus dans\S
.mary@aolcom
que comme je suis une ordure complète . YMMV.@
signes:/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/
jsfiddle.net/b9chris/mXB96Cela dépend de ce que vous entendez par mieux: si vous parlez d'attraper chaque adresse e-mail valide, utilisez ce qui suit:
( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Si vous cherchez quelque chose de plus simple mais qui captera la plupart des adresses e-mail valides, essayez quelque chose comme:
EDIT: A partir du lien:
la source
email address
qui traversent à tort le second, mais sont capturés par l'expression régulière plus longue?[MISE À JOUR] J'ai rassemblé tout ce que je sais sur la validation des adresses e-mail ici: http://isemail.info , qui non seulement valide mais diagnostique désormais les problèmes avec les adresses e-mail. Je suis d'accord avec de nombreux commentaires ici que la validation n'est qu'une partie de la réponse; voir mon essai à http://isemail.info/about .
is_email () reste, pour autant que je sache, le seul validateur qui vous dira définitivement si une chaîne donnée est une adresse e-mail valide ou non. J'ai téléchargé une nouvelle version sur http://isemail.info/
J'ai rassemblé des cas de test de Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 et RFC 3696. 275 adresses de test en tout. J'ai exécuté tous ces tests contre tous les validateurs gratuits que j'ai pu trouver.
J'essaierai de garder cette page à jour pendant 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 les critiques constructives de mon propre validateur .
Les gens doivent être conscients des 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, pas 320.
la source
[email protected]
car ce code concerne la validation, pas l'interprétation. Si vous souhaitez ajouter un traducteur punycode, je suis heureux d'accepter une demande d'extraction sur github.com/dominicsayers/isemailSelon les spécifications HTML5 du W3C :
Le contexte:
la source
john.doe@localhost
est valide. Bien sûr, dans une application réelle (c'est-à-dire une communauté), j'aimerais que votre suggestion remplace * par +"test...."@gmail.com
est parfaitement valide selon la RFC et sémantiquement équivalent à[email protected]
.C'est facile en Perl 5.10 ou plus récent:
la source
addrspec
partie est vraiment pertinent pour la question. Accepter plus que cela et le transmettre si une autre partie du système qui n'est pas prête à accepter les adresses RFC5822 complètes, c'est comme si la prise de vue était votre propre pied.j'utilise
Qui est celui utilisé dans ASP.NET par le RegularExpressionValidator.
la source
[email protected]
est rejetée.^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w{2,}([-.]\\w+)*$
[email protected]
qui est en fait valide (un de nos clients avait une adresse similaire) `Je ne sais pas ce qu'il y a de mieux, mais celui-ci est au moins correct, tant que les adresses ont leurs commentaires supprimés 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 simplement un e-mail de vérification à cette adresse.
la source
Les adresses e-mail que je souhaite valider seront utilisées par une application Web ASP.NET utilisant l'espace de noms System.Net.Mail 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 simplement de créer une instance MailAddress à partir de l'adresse. Le constructeur MailAddress lèvera une exception si l'adresse n'est pas correctement formée. De cette façon, je sais que je peux au moins sortir le courrier électronique de la porte. Bien sûr, il s'agit d'une validation côté serveur, mais au minimum, vous en avez besoin de toute façon.
la source
args.Value
au lieu de référencer le champ commetxtEmail.Text
codé en dur. Ce dernier liera votre validateur à l'instance de contrôle unique, ce qui peut être OK, tant que vous avez un seul champ e-mail, mais non recommandé autrement.Réponse rapide
Utilisez l'expression régulière suivante 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 à cette expression régulière:
La deuxième contrainte est une restriction sur RFC 5321/5322.
Réponse élaborée
L'utilisation d'une expression régulière qui reconnaît les adresses e-mail peut être utile dans diverses situations: par exemple pour rechercher des adresses e-mail dans un document, pour valider la saisie de l'utilisateur ou comme contrainte d'intégrité sur un référentiel de données.
Il convient toutefois de noter que si vous souhaitez savoir si l'adresse fait réellement référence à une boîte aux lettres existante, rien ne peut remplacer l'envoi d'un message à l'adresse. Si vous souhaitez uniquement vérifier si une adresse est grammaticalement correcte, vous pouvez utiliser une expression régulière, mais notez que
""@[]
s'agit d'une adresse e-mail grammaticalement correcte qui ne fait certainement pas référence à 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 norme. La syntaxe définie dans la RFC 822 est la plus clémente et les normes ultérieures ont restreint la syntaxe de plus en plus, où les nouveaux systèmes ou services devraient reconnaître la syntaxe obsolète, mais ne jamais la produire.
Dans cette réponse, je considérerai «adresse e-mail»
addr-spec
comme défini dans les RFC (c'est[email protected]
-à- dire , mais pas"John Doe"<[email protected]>
, nisome-group:[email protected],[email protected];
).Il y a un problème avec la traduction des syntaxes RFC en expressions régulières: les syntaxes ne sont pas régulières! En effet, ils permettent des commentaires facultatifs dans les adresses e-mail qui peuvent être imbriquées à l'infini, tandis que l'imbrication à l'infini ne peut pas être décrite 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 langages comme Perl ont des constructions pour décrire les grammaires sans contexte d'une manière regex.) Dans cette réponse, je vais ignorer les commentaires et ne considérer que les expressions régulières appropriées.
Les RFC définissent les syntaxes des e-mails et non des adresses e-mail 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 sauts de ligne. Sémantiquement, cela n'a cependant aucune signification. En supprimant cet espace, etc. d'une adresse, vous obtenez une représentation canonique sémantiquement équivalente . Ainsi, la représentation canonique de
first. last (comment) @ [3.5.7.9]
estfirst.last@[3.5.7.9]
.Différentes syntaxes doivent être utilisées à 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. En revanche, si vous souhaitez valider la saisie utilisateur, vous pouvez utiliser le syntaxe telle que définie dans la RFC 5322, n'acceptant probablement que des représentations canoniques. Vous devez décider quelle syntaxe s'applique à votre cas spécifique.
J'utilise des expressions régulières "étendues" 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 le casser. Si vous trouvez des faux positifs ou des faux négatifs, veuillez les poster dans un commentaire et j'essaierai 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, y compris les errata . Il reconnaît uniquement les adresses e-mail sous leur forme canonique. Pour une expression régulière qui reconnaît (pliant) les espaces blancs, voir la dérivation ci-dessous.
La dérivation montre comment je suis arrivé à l'expression. Je liste toutes les règles de grammaire pertinentes de la RFC exactement telles qu'elles apparaissent, suivies de l'expression rationnelle correspondante. 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 suivantes.
Comme indiqué au paragraphe 3.1.4. du RFC 822, un espace blanc linéaire optionnel peut être inséré entre les jetons lexicaux. Le cas échéant, j'ai développé les expressions pour tenir compte de cette règle et marqué le résultat avec "opt-lwsp".
RFC 5322
Je suis arrivé à l'expression régulière suivante. J'invite tout le monde à essayer de le casser. Si vous trouvez des faux positifs ou des faux négatifs, veuillez les poster dans un commentaire et j'essaierai 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 les errata . Il reconnaît uniquement les adresses e-mail sous leur forme canonique. Pour une expression régulière qui reconnaît (pliant) les espaces blancs, voir la dérivation ci-dessous.
La dérivation montre comment je suis arrivé à l'expression. Je liste toutes les règles de grammaire pertinentes de la RFC exactement telles qu'elles apparaissent, suivies de l'expression rationnelle correspondante. Pour les règles qui incluent des espaces blancs sémantiquement non pertinents (pliants), je donne une expression régulière distincte marquée "(normalisée)" qui n'accepte pas ces espaces blancs.
J'ai ignoré toutes les règles "obs-" de la RFC. Cela signifie que les expressions rationnelles correspondent uniquement aux adresses e-mail strictement conformes à la RFC 5322. Si vous devez faire correspondre les «anciennes» adresses (comme le fait la grammaire plus souple, y compris les règles «obs»), vous pouvez utiliser l'une des expressions rationnelles RFC 822 du paragraphe précédent.
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 @ -sign). En effet, "..", "a..b" et "a". ne sont pas des atomes de point valides, alors qu'ils peuvent être utilisés comme noms de boîtes aux lettres. Le RFC, cependant, ne permet de pièces locales comme celles - ci, sauf qu'ils doivent être cités. Donc au lieu de
[email protected]
vous devriez écrire"a..b"@example.net
, ce qui est sémantiquement équivalent.D'autres restrictions
SMTP (tel que défini dans la RFC 5321 ) restreint davantage l'ensemble des adresses e-mail valides (ou en fait: les noms de boîtes aux lettres). Il semble raisonnable d'imposer cette grammaire plus stricte, afin que l'adresse e-mail correspondante puisse être utilisée pour envoyer un e-mail.
La RFC 5321 laisse essentiellement la partie "locale" (c'est-à-dire la partie avant le @ -sign), mais est plus stricte sur la partie du domaine (c'est-à-dire la partie après le @ -sign). Il autorise uniquement les noms d'hôte à la place des atomes de point et les littéraux d'adresse à la place des littéraux de domaine.
La grammaire présentée dans RFC 5321 est trop indulgente en ce qui concerne à la fois les noms d'hôte et les adresses IP. J'ai pris la liberté de "corriger" les règles en question, en utilisant ce projet et la RFC 1034 comme lignes directrices. Voici l'expression régulière 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^-~]+)])
Notez que selon le cas d'utilisation, vous ne voudrez peut-être pas autoriser un "littéral d'adresse générale" dans votre expression régulière. Notez également que j'ai utilisé un lookahead négatif
(?!IPv6:)
dans l' expression régulière pour empêcher la partie "General-address-literal" de faire correspondre les adresses IPv6 malformées. Certains processeurs regex ne prennent pas en charge l'anticipation négative. Retirez la sous-chaîne|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+
de l'expression régulière si vous souhaitez supprimer toute la partie "General-address-literal".Voici la dérivation:
Validation des entrées utilisateur
Un cas d'utilisation courant est la validation des entrées utilisateur, par exemple sur un formulaire html. Dans ce cas, il est généralement raisonnable d'exclure les littéraux d'adresse et d'exiger au moins deux étiquettes dans le nom d'hôte. En prenant comme base l'expression rationnelle RFC 5321 améliorée 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 entre guillemets, car nous ne savons pas quel type de noms de boîte aux lettres certains hôtes autorisent (comme
"a..b"@example.net
ou même"a b"@example.net
).Je ne recommande pas non plus de valider explicitement par rapport à une liste de domaines de premier niveau littéraux ou même d'imposer des contraintes de longueur (rappelez-vous comment ".museum" est 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écidez de suivre le chemin de la validation explicite de domaine de premier niveau.
Considérations supplémentaires
Lorsqu'ils acceptent uniquement les noms d'hôte dans la partie domaine (après le signe @), les expressions rationnelles ci-dessus n'acceptent que les étiquettes avec au plus 63 caractères, comme elles le devraient. Cependant, ils n'imposent pas le fait que le nom d'hôte entier doit contenir au plus 253 caractères (y compris les points). Bien que cette contrainte soit à proprement parler encore régulière, il n'est pas possible de faire une regex qui incorpore cette règle.
Une autre considération, en particulier lors de l'utilisation des expressions rationnelles pour la validation des entrées, est le retour d'information à l'utilisateur. Si un utilisateur entre une adresse incorrecte, ce serait bien de donner un peu plus de commentaires qu'une simple "adresse syntaxiquement incorrecte". Avec les expressions régulières "vanille", ce n'est pas possible.
Ces deux considérations pourraient être traitées en analysant l'adresse. Dans certains cas, la contrainte de longueur supplémentaire sur les noms d'hôte peut également être traitée en utilisant une expression régulière supplémentaire qui la vérifie et en faisant correspondre l'adresse avec les deux expressions.
Aucun des regex de cette réponse n'est optimisé pour les performances. Si les performances posent problème, vous devriez voir si (et comment) l'expression rationnelle de votre choix peut être optimisée.
la source
arbitrary-long-email-address-should-be-invalid-arbitrary-long-email-address-should-be-invalid.and-the-second-group-also-should-not-be-so-long-and-the-second-group-also-should-not-be-so-long@example.com
, ne devrait pas valider. Je suggère de changer les signes "+" dans le premier groupe (nom avant le point facultatif) et dans le deuxième groupe (nom après les points suivants) en{1,64}
$emailRegex = '/^([-!#-\'*+\/-9=?A-Z^-~]{1,64}(\.[-!#-\'*+\/-9=?A-Z^-~]{1,64})*|"([]!#-[^-~ \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])?)+$/';
Il existe de nombreux exemples de cela sur le net (et je pense que même un qui valide pleinement le RFC - mais il fait des dizaines / centaines de lignes si la mémoire est bonne). Les gens ont tendance à s'emballer en validant ce genre de choses. Pourquoi ne pas simplement vérifier qu'il a un @ et au moins un. et répond à une longueur minimale simple. Il est trivial de saisir un faux e-mail et de toujours correspondre à toute expression rationnelle valide. Je suppose que les faux positifs valent mieux que les faux négatifs.
la source
Lorsque vous décidez quels caractères sont autorisés, n'oubliez pas vos amis apostrophés 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 à partir du système RH. Cela inclut l'apostrophe dans mon nom de famille. Je ne peux pas vous dire combien de fois j'ai été empêché d'interagir avec un site Web du fait que mon adresse e-mail est "invalide".
la source
Cette expression régulière provient de la bibliothèque Email :: Valid de Perl . Je pense que c'est le plus précis, il correspond à tous les 822. Et, il est basé sur l'expression régulière dans le livre O'Reilly:
la source
Lorsque vous écrivez en PHP, je vous conseille d'utiliser la validation intégrée PHP pour les e-mails.
Si vous utilisez une version php inférieure à 5.3.6, veuillez être conscient de ce problème: https://bugs.php.net/bug.php?id=53091
Si vous souhaitez plus d'informations sur le fonctionnement de cette validation intégrée, voir ici: Le filtre filter_var FILTER_VALIDATE_EMAIL de PHP fonctionne-t-il réellement?
la source
Cal Henderson (Flickr) a écrit un article intitulé Parsing Email Adresses en PHP et montre comment effectuer une analyse correcte des adresses e-mail conformes à la RFC (2) 822. Vous pouvez également obtenir le code source en php , python et ruby sous licence cc .
la source
a@b
c'était validea@b
est valide ... dans ce casb
est le domaine de premier niveau.Je n'ai jamais pris la peine de créer avec ma propre expression régulière, car il est probable que quelqu'un d'autre ait déjà trouvé une meilleure version. J'utilise toujours regexlib pour en trouver un à mon goût.
la source
Il n'y en a pas de vraiment utilisable.
Je discute de certains problèmes dans ma réponse à Existe-t-il une bibliothèque php pour la validation de l'adresse e-mail? , il est également abordé dans Regexp reconnaissance d'adresse e-mail difficile?
En bref, ne vous attendez pas à ce qu'une seule expression rationnelle utilisable fasse un bon travail. Et le meilleur regex validera la syntaxe, pas la validité d'un e-mail ([email protected] est correct mais il rebondira probablement ...).
la source
Une expression régulière simple qui ne rejetterait au moins aucune adresse e-mail valide serait de vérifier quelque chose, suivi d'un signe @ puis de quelque chose suivi d'un point et d'au moins 2 choses. Il ne rejettera rien, mais après avoir examiné les spécifications, je ne trouve aucun e-mail qui serait valide et rejeté.
email = ~
/.+@[^@]+\.[^@]{2,}$/
la source
/^[^@]+@[^@]+\.[^@]{2}[^@]*$/
vérifie réellement le signe 1 @. Votre expression régulière laissera passer plusieurs fois à cause du. * À la fin./^[^@]+@[^@]+\.[^@]{2,4}$/
s'assurer qu'il se termine par 2 à 4 caractères non @. Comme l'a souligné @Josh, il permet désormais un @ supplémentaire à la fin. Mais vous pouvez également changer cela en:/^[^@]+@[^@]+\.[^a-z-A-Z]{2,4}$/
puisque tous les domaines de premier niveau sont des caractères aZ. vous pouvez remplacer le4
par5
ou plus, permettant ainsi aux noms de domaine de premier niveau d'être plus longs à l'avenir.Vous pouvez utiliser celui utilisé par le plugin jQuery Validation:
la source
a-b'[email protected]
mais a pua-b'[email protected]
a-b'[email protected]
Pour l'évaluation la plus complète de la meilleure expression régulière pour valider une adresse e-mail, veuillez consulter ce lien; " Comparaison des adresses e-mail de validation des expressions régulières "
Voici l'expression top actuelle à des fins de référence:
la source
Sans oublier que les noms de domaine non latins (chinois, arabe, grec, hébreu, cyrillique, etc.) doivent être autorisés dans un proche avenir . Tout le monde doit changer l'expression rationnelle utilisée pour les e-mails, car ces caractères ne doivent certainement pas être couverts par
[a-z]/i
ni\w
. Ils échoueront tous.Après tout, la meilleure façon de valider l'adresse e-mail est toujours d' envoyer réellement un e-mail à l'adresse en question pour valider l'adresse. Si l'adresse e-mail fait partie de l'authentification des utilisateurs (inscription / connexion / etc), vous pouvez parfaitement la combiner avec le système d'activation des utilisateurs. C'est-à-dire envoyer un e-mail avec un lien avec une clé d'activation unique à l'adresse e-mail spécifiée et autoriser la connexion uniquement lorsque l'utilisateur a activé le compte nouvellement créé en utilisant le lien dans l'e-mail.
Si le but de l'expression régulière est simplement d'informer rapidement l'utilisateur dans l'interface utilisateur que l'adresse e-mail spécifiée ne ressemble pas au bon format, le mieux est encore de vérifier si elle correspond fondamentalement à l'expression régulière suivante:
Aussi simple que cela. Pourquoi diable vous soucieriez-vous des caractères utilisés dans le nom et le domaine? Il est de la responsabilité du client d'entrer une adresse e-mail valide, pas celle du serveur. Même lorsque le client entre une adresse e-mail syntaxiquement valide comme
[email protected]
, cela ne garantit pas qu'il s'agit d'une adresse e-mail légitime. Aucun regex ne peut couvrir cela.la source
spaces
après le@.
eg.[email protected] com net
est considéré comme un e-mail valide en utilisant l'expression rationnelle ci-dessus, alors qu'il devrait être non valide.La spécification HTML5 suggère une expression régulière simple pour valider les adresses e-mail:
Cela n'est pas intentionnellement conforme à la RFC 5322 .
La longueur totale pourrait également être limitée à 254 caractères, selon les errata RFC 3696 1690 .
la source
invalid@emailaddress
. Je vous conseille de faire preuve de prudence et de nombreux tests avant de l'utiliser!Pour une démonstration vivante, le monstre suivant est assez bon mais ne reconnaît toujours pas correctement toutes les adresses e-mail syntaxiquement valides: il reconnaît les commentaires imbriqués jusqu'à quatre niveaux de profondeur.
Il s'agit d'un travail pour un analyseur, mais même si une adresse est syntaxiquement valide, elle peut ne pas être livrable. Parfois, vous devez recourir à la méthode Hillbilly de "Hé, vous tous, regardez-nous!"
la source
Selon la norme officielle RFC 2822, l' expression régulière des e-mails valides est
si vous voulez l'utiliser en Java, c'est vraiment très facile
la source
(?:[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-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])+)\])
Voici le PHP que j'utilise. J'ai choisi cette solution dans l'esprit des "faux positifs valent mieux que les faux négatifs" comme déclaré par un autre commentateur ici ET en ce qui concerne le maintien de votre temps de réponse et la charge du serveur ... il n'y a vraiment pas besoin de gaspiller les ressources du serveur avec une expression régulière lorsque cela éliminera l'erreur utilisateur la plus simple. Vous pouvez toujours suivre cela en envoyant un e-mail de test si vous le souhaitez.
la source
Norme RFC 5322:
Autorise la partie locale de l'atome point, la partie locale de chaîne entre guillemets, la partie locale obsolète (atome de point mélangé et la chaîne entre guillemets), le domaine de nom de domaine, le domaine littéral de domaine (adresse IPv4, IPv6 et IPv6 mappée IPv6), et (imbriqué) CFWS.
Norme RFC 5321:
Autorise la partie locale à point atomique, la partie locale de chaîne entre guillemets, le domaine de nom de domaine et le domaine (IPv4, IPv6 et IPv4 mappé IPv6) domaine littéral domaine.
De base:
Permet la partie locale et le domaine de nom de domaine atomique (nécessitant au moins deux étiquettes de nom de domaine avec le TLD limité à 2 à 6 caractères alphabétiques).
la source
/D
drapeau, et vous l'avez cité avec des guillemets simples, mais vous avez également utilisé des barres obliques pour délimiter le motif? Ce n'est pas Perl, et ce ne peut pas être PCRE. Est-ce donc PHP? Je crois que ce sont les trois seuls qui permettent la récursivité comme(?1)
.Étrange que vous ne puissiez pas autoriser des TLD à 4 caractères. Vous interdisez les utilisateurs de .info et .name , et la limitation de longueur arrête .travel et .museum , mais oui, ils sont moins courants que les TLD à 2 caractères et les TLD à 3 caractères.
Vous devez également autoriser les alphabets majuscules. Les systèmes de messagerie normaliseront la partie locale et la partie domaine.
Pour votre expression régulière de la partie domaine, le nom de domaine ne peut pas commencer par «-» et ne peut pas se terminer par «-». Dash ne peut que rester entre les deux.
Si vous avez utilisé la bibliothèque PEAR, consultez leur fonction de messagerie (oublié le nom exact / bibliothèque). Vous pouvez valider l'adresse e-mail en appelant une fonction, et cela valide l'adresse e-mail conformément à la définition dans RFC822.
la source
la source