230 votes

Comment vérifier si l'adresse électronique est valide ?

Existe-t-il un bon moyen de vérifier une entrée de formulaire à l'aide d'une expression rationnelle pour s'assurer qu'il s'agit d'une adresse électronique correcte ? J'ai cherché depuis hier soir et toutes les personnes qui ont répondu aux questions des gens à ce sujet semblent également avoir des problèmes si l'adresse électronique est un sous-domaine.

312voto

Thomas Points 63635

Il n'y a aucun intérêt. Même si vous pouvez vérifier que l'adresse électronique est syntaxiquement valide, vous devez encore vérifier qu'elle n'a pas été mal saisie et qu'elle est bien destinée à la personne à laquelle vous pensez. Le seul moyen d'y parvenir est de lui envoyer un courrier électronique et de lui demander de cliquer sur un lien pour le vérifier.

Par conséquent, une vérification de base (par exemple, vérifier qu'ils n'ont pas saisi leur adresse par erreur) est généralement suffisante. Quelque chose comme : il a exactement un @ et au moins un . dans la partie après le @ :

[^@]+@[^@]+\.[^@]+

Vous voudrez probablement aussi interdire les espaces -- il existe probablement des adresses électroniques valides comportant des espaces, mais je n'en ai jamais vu, donc les chances que ce soit une erreur de l'utilisateur sont de votre côté.

Si vous voulez le contrôle complet, jetez un coup d'oeil à cette question .


Mise à jour : Voici comment utiliser une telle regex :

import re

if not re.match(r"... regex here ...", email):
  # whatever

Python 3.4 a re.fullmatch qui est préférable à re.match .

Notez le r devant la chaîne ; de cette façon, vous n'aurez pas besoin d'échapper les choses deux fois.

Si vous avez un grand nombre de regex à vérifier, il peut être plus rapide de compiler d'abord le regex :

import re

EMAIL_REGEX = re.compile(r"... regex here ...")

if not EMAIL_REGEX.match(email):
  # whatever

Une autre option consiste à utiliser le validate_email qui contacte effectivement le serveur SMTP pour vérifier que l'adresse existe. Mais cela ne garantit toujours pas que l'adresse appartient à la bonne personne.

1 votes

Donc, en gros, ma meilleure option serait if not re.match("[^@]+@[^@]+\.[^@]+", email): ?

25 votes

J'ai fini par faire if not re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$"‌​, email): car cela semble être le scénario le plus plausible, suivi de l'envoi d'un courriel de vérification à l'adresse indiquée.

0 votes

+1 pour le tutoriel rapide re.match(r "xx"). Inliner ce qui est nécessaire est la marque d'une bonne réponse.

149voto

LeoRochael Points 401

La bibliothèque standard Python est livrée avec une fonction d'analyse syntaxique des e-mails : email.utils.parseaddr() .

Il renvoie un couple contenant le nom réel et l'adresse réelle de l'e-mail :

>>> from email.utils import parseaddr
>>> parseaddr('foo@example.com')
('', 'foo@example.com')

>>> parseaddr('Full Name <full@example.com>')
('Full Name', 'full@example.com')

>>> parseaddr('"Full Name with quotes and <weird@chars.com>" <weird@example.com>')
('Full Name with quotes and <weird@chars.com>', 'weird@example.com')

Et si l'analyse syntaxique n'aboutit pas, elle renvoie un doublet de chaînes de caractères vides :

>>> parseaddr('[invalid!email]')
('', '')

Un problème avec cet analyseur est qu'il accepte tout ce qui est considéré comme une adresse e-mail valide pour RFC-822 et ses amis, y compris beaucoup de choses qui ne sont clairement pas adressables sur l'Internet :

>>> parseaddr('invalid@example,com') # notice the comma
('', 'invalid@example')

>>> parseaddr('invalid-email')
('', 'invalid-email')

Ainsi, comme le dit @TokenMacGuy, la seule façon définitive de vérifier une adresse électronique est d'envoyer un courrier électronique à l'adresse attendue et d'attendre que l'utilisateur agisse en fonction des informations contenues dans le message.

Cependant, vous pourriez vouloir vérifier, au moins, la présence d'un signe @ sur le deuxième élément du tuple, comme le suggère @bvukelic :

>>> '@' in parseaddr("invalid-email")[1]
False

Si vous voulez aller un peu plus loin, vous pouvez installer le programme dnspython et résoudre les serveurs de messagerie pour le domaine de courrier électronique (la partie après le '@'), en essayant d'envoyer un courrier électronique uniquement s'il y a des serveurs réels. MX serveurs :

>>> from dns.resolver import query
>>> domain = 'foo@bar@google.com'.rsplit('@', 1)[-1]
>>> bool(query(domain, 'MX'))
True
>>> query('example.com', 'MX')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  [...]
dns.resolver.NoAnswer
>>> query('not-a-domain', 'MX')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  [...]
dns.resolver.NXDOMAIN

Vous pouvez attraper les deux NoAnswer et NXDOMAIN en attrapant dns.exception.DNSException .

Et oui, foo@bar@google.com est une adresse syntaxiquement valide. Seule la dernière @ doit être prise en compte pour détecter où commence la partie du domaine.

5 votes

@PeterLada : Tu pourrais juste vérifier s'il y a un @ dans l'adresse après avoir utilisé ce func, cependant.

0 votes

@PeterLada, Merci pour votre contribution. J'ai corrigé le nom du module.

1 votes

parseaddr(u"evil@addr") va casser ça.

23voto

bigendian Points 430

Les adresses électroniques ne sont pas aussi simples qu'elles le paraissent ! Par exemple, Bob_O'Reilly+tag@example.com, est une adresse électronique valide.

J'ai eu un peu de chance avec le paquet lepl ( http://www.acooke.org/lepl/ ). Il peut valider les adresses électroniques comme indiqué dans la RFC 3696 : http://www.faqs.org/rfcs/rfc3696.html

J'ai trouvé un vieux code :

import lepl.apps.rfc3696
email_validator = lepl.apps.rfc3696.Email()
if not email_validator("email@example.com"):
    print "Invalid email"

15 votes

lepl a été supprimé.

3 votes

Pour un cas d'utilisation simple comme celui-ci, si la version actuelle fonctionne, le fait qu'elle soit abandonnée n'est pas très pertinent.

1 votes

Cette méthode ne fonctionne pas quand u met email email''sfsf@sadasdas.adsdsa.com.com' Il retourne vrai pour ce nom d'utilisateur aussi

5voto

Mithon Points 2410

Ce problème est généralement résolu à l'aide d'une expression rationnelle. Il existe toutefois de nombreuses variantes de solutions. Tout dépend de la rigueur dont vous avez besoin, et si vous avez des exigences personnalisées en matière de validation, ou si vous acceptez toute adresse électronique valide.

Voir cette page à titre de référence : http://www.regular-expressions.info/email.html

4voto

Dan Points 7970

Les adresses e-mail sont incroyablement compliquées. Voici un exemple d'expression rationnelle qui correspondra à toutes les adresses valides selon la norme RFC822 : http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html

Vous remarquerez qu'il est probablement plus long que le reste de votre programme. Il existe même des modules entiers pour Perl dont le but est de valider les adresses électroniques. Vous n'obtiendrez donc probablement rien qui soit à 100% parfait en tant que regex tout en étant lisible. Voici un exemple d'analyseur récursif descendant : http://cpansearch.perl.org/src/ABIGAIL/RFC-RFC822-Address-2009110702/lib/RFC/RFC822/Address.pm

mais vous devrez décider si vous avez besoin d'une analyse syntaxique parfaite ou d'un code simple.

Prograide.com

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

Powered by:

X