检查 django/python 中电子邮件的有效性

我已经写了一个函数添加电子邮件到通讯基地。直到我增加了检查发送的电子邮件的有效性,它的工作完美无缺。现在每次我都收到“错误的邮件”作为回复。有人看到这里有什么错误吗?使用的正则表达式是:

\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b和它是100% 有效的(http://gskinner.com/RegExr/) ,但是我可能使用它是错误的,或者它可能是一些逻辑错误:

def newsletter_add(request):
if request.method == "POST":
try:
e = NewsletterEmails.objects.get(email = request.POST['email'])
message = _(u"Email is already added.")
type = "error"
except NewsletterEmails.DoesNotExist:
if validateEmail(request.POST['email']):
try:
e = NewsletterEmails(email = request.POST['email'])
except DoesNotExist:
pass
message = _(u"Email added.")
type = "success"
e.save()
else:
message = _(u"Wrong email")
type = "error"


import re


def validateEmail(email):
if len(email) > 6:
if re.match('\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b', email) != None:
return 1
return 0
113933 次浏览

Ick, no, please, don't try to validate email addresses yourself. It's one of those things people never get right.

Your safest option, since you're already using Django, is to just take advantage of its form validation for email. Per the docs:

>>> from django import forms
>>> f = forms.EmailField()
>>> f.clean('foo@example.com')
u'foo@example.com'
>>> f.clean(u'foo@example.com')
u'foo@example.com'
>>> f.clean('invalid e-mail address')
...
ValidationError: [u'Enter a valid e-mail address.']

You got it wrong, but it is a task that you can't do anyway. There is one and only one way to know if an RFC 2822 address is valid, and that is to send mail to it and get a response. Doing anything else doesn't improve the information content of your datum by even a fractional bit.

You also screw the human factor and acceptance property, for when you give validateEmail my address of

me+valid@mydomain.example.net

and you tell me I've made an error, I tell your application goodbye.

UPDATE 2017: the code below is 7 years old and was since modified, fixed and expanded. For anyone wishing to do this now, the correct code lives around here.

Here is part of django.core.validators you may find interesting :)

class EmailValidator(RegexValidator):


def __call__(self, value):
try:
super(EmailValidator, self).__call__(value)
except ValidationError, e:
# Trivial case failed. Try for possible IDN domain-part
if value and u'@' in value:
parts = value.split(u'@')
domain_part = parts[-1]
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
super(EmailValidator, self).__call__(u'@'.join(parts))
else:
raise


email_re = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')

so if you don't want to use forms and form fields, you can import email_re and use it in your function, or even better - import validate_email and use it, catching possible ValidationError.

def validateEmail( email ):
from django.core.validators import validate_email
from django.core.exceptions import ValidationError
try:
validate_email( email )
return True
except ValidationError:
return False

And here is Mail::RFC822::Address regexp used in PERL, if you really need to be that paranoid.

Change your code from this:

re.match('\b[\w.-]+@[\w.-]+.\w{2,4}\b', email)

to this:

re.match(r'\b[\w.-]+@[\w.-]+.\w{2,4}\b', email)

works fine with me.

from django.core.exceptions import ValidationError
from django.core.validators import validate_email


value = "foo.bar@baz.qux"


try:
validate_email(value)
except ValidationError as e:
print("bad email, details:", e)
else:
print("good email")

This regex will validate an email address with reasonable accuracy.

\w[\w\.-]*@\w[\w\.-]+\.\w+

It allows alphanumeric characters, _, . and -.

I can see many answers here are based on django framework of python. But for verifying an email address why to install such an heavy software. We have the Validate_email package for Python that check if an email is valid, properly formatted and really exists. Its a light weight package (size < 1MB).

INSTALLATION :

pip install validate_email

Basic usage:

Checks whether email is in proper format.

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

To check the domain mx and verify email exists you can install the pyDNS package along with validate_email.

Verify email exists :

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

Returns True if the email exist in real world else False.