关于正则表达式:在django / python中检查电子邮件的有效性

Checking validity of email in django/python

本问题已经有最佳答案,请猛点这里访问。

我已经编写了一个向时事通讯库添加电子邮件的函数。直到我添加了检查已发送电子邮件的有效性,它才能完美地工作。现在,每次我收到"错误的电子邮件"作为回报。有人能在这里看到任何错误吗?使用的regex是:

EDCOX1,0,它是100%有效的(http://gSnnn.com/ReGeRr/),但是我可能使用它错误,或者它可能是一些逻辑错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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


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: https://github.com/django/django/blob/master/django/core/validators.py#L168-L180

下面是django.core.validator的一部分,您可能会发现它很有趣:)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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')

因此,如果不想使用表单和表单字段,可以导入email_re并在函数中使用它,或者更好地导入validate_email并使用它,捕获可能的ValidationError

1
2
3
4
5
6
7
8
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

这里是mail::rfc822::address regexp,在Perl中使用,如果您真的需要这样的偏执狂的话。


1
2
3
4
5
6
7
8
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
try:
    validate_email("[email protected]")
except ValidationError as e:
    print"oops! wrong email"
else:
    print"hooray! email is valid"


请不要试图自己验证电子邮件地址。这是人们永远不会改正的事情之一。

因为您已经在使用django,所以最安全的选择就是利用它的电子邮件表单验证。根据文件(http://docs.djangoproject.com/en/dev/ref/forms/fields/):

1
2
3
4
5
6
7
8
9
>>> from django import forms
>>> f = forms.EmailField()
>>> f.clean('[email protected]')
u'[email protected]'
>>> f.clean(u'[email protected]')
u'[email protected]'
>>> f.clean('invalid e-mail address')
...
ValidationError: [u'Enter a valid e-mail address.']


你搞错了,但这是你无论如何都做不到的任务。知道RFC2822地址是否有效只有一种方法,那就是向它发送邮件并得到响应。做任何其他的事情都不会提高数据的信息内容,甚至一点点。

你还搞砸了人为因素和接受财产,因为当你把我的地址

1
me+valid@mydomain.example.net

你告诉我我犯了一个错误,我跟你的申请说再见。


我可以看到很多答案都是基于Python的django框架。但为了验证电子邮件地址,为什么要安装这么重的软件。我们有针对python的validate_email包,用于检查电子邮件是否有效、格式是否正确以及是否真的存在。它是一个重量轻的包装(尺寸<1MB)。

安装:

1
pip install validate_email

基本用法:

检查电子邮件的格式是否正确。

1
2
from validate_email import validate_email
is_valid = validate_email('[email protected]')

要检查域MX并验证电子邮件是否存在,您可以安装pydns包以及validate_电子邮件。

验证电子邮件是否存在:

1
2
from validate_email import validate_email
is_valid = validate_email('[email protected]',verify=True)

如果电子邮件存在于真实世界中,则返回"真",否则返回"假"。


此regex将以合理的准确性验证电子邮件地址。

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

它允许字母数字字符:_.-


从此处更改代码:

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

对此:

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

和我一起工作很好。