Python check for valid email address?

Is there a good way to check a form input using regex to make sure it is a proper style email address? Been searching since last night and everybody that has answered peoples questions regarding this topic also seems to have problems with it if it is a subdomained email address.


There is no point. Even if you can verify that the email address is syntactically valid, you'll still need to check that it was not mistyped, and that it actually goes to the person you think it does. The only way to do that is to send them an email and have them click a link to verify.

Therefore, a most basic check (eg that they didn't accidentally entered their street address) is usually enough. Something like: it has exactly one @ sign, and at least one . in the part after the @ :

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

You'd probably also want to disallow whitespace -- there are probably valid email addresses with whitespace in them, but I've never seen one, so the odds of this being a user error are on your side.

If you want the full check, have a look at this question.


Update: Here's how you could use any such regex:

import re

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

Note the r in front of the string; this way, you won't need to escape things twice.

If you have a large number of regexes to check, it might be faster to compile the regex first:

import re

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

if not EMAIL_REGEX.match(email):
  # whatever

The Python standard library comes with an e-mail parsing function: email.utils.parseaddr() .

It returns a two-tuple containing the real name and the actual address parts of the 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')

And if the parsing is unsuccessful, it returns a two-tuple of empty strings:

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

An issue with this parser is that it's accepting of anything that is considered as a valid e-mail address for RFC-822 and friends, including many things that are clearly not addressable on the wide Internet:

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

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

So, as @TokenMacGuy put it, the only definitive way of checking an e-mail address is to send an e-mail to the expected address and wait for the user to act on the information inside the message.

However, you might want to check for, at least, the presence of an @-sign on the second tuple element, as @bvukelic suggests:

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

If you want to go a step further, you can install the dnspython project (or this one for Python 3) and resolve the mail servers for the e-mail domain (the part after the '@'), only trying to send an e-mail if there are actual MX servers:

>>> 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

You can catch both NoAnswer and NXDOMAIN by catching dns.exception.DNSException .

And Yes, foo@bar@google.com is a syntactically valid address. Only the last @ should be considered for detecting where the domain part starts.


I haven't seen the answer already here among the mess of custom Regex answers, but...

Python has a module called validate_email which has 3 levels of email validation, including asking a valid SMTP server if the email address is valid (without sending an email).

Check email string is valid format:

from validate_email import validate_email
is_valid = validate_email('example@example.com')

Check if the host has SMTP Server:

is_valid = validate_email('example@example.com',check_mx=True)

Check if the host has SMTP Server and the email really exists:

is_valid = validate_email('example@example.com',verify=True)

For those interested in the dirty details, validate_email.py (source) aims to be faithful to RFC 2822.

All we are really doing is comparing the input string to one gigantic regular expression. But building that regexp, and ensuring its correctness, is made much easier by assembling it from the "tokens" defined by the RFC. Each of these tokens is tested in the accompanying unit test file.


To install with pip

pip install validate_email

and you'll need the pyDNS module for checking SMTP servers

pip install pyDNS
链接地址: http://www.djcxy.com/p/92934.html

上一篇: 如何验证PHP中的电子邮件地址

下一篇: Python检查有效的电子邮件地址?