2010-07-10 79 views
53

我已经写了一个函数用于向通讯库添加电子邮件。在我添加检查发送的电子邮件的有效性之前,它的工作完美无瑕。现在每次我收到“错误的电子邮件”。任何人都可以在这里看到任何错误?所使用的正则表达式是:在django/python中检查电子邮件的有效性

\b[\w\.-][email protected][\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\.-][email protected][\w\.-]+\.\w{2,4}\b', email) != None: 
      return 1 
    return 0 
+4

100%有效吗?不符合'foo + bar @ example.com',不会匹配'foo @ museum.com',而且更多。 – Kos 2013-12-23 10:37:26

+0

100%有效?你的正则表达式匹配'a .. @ .............. a'。 – Zenadix 2014-09-25 21:01:41

回答

131

更新2017:下面的代码是7岁,并已修改,固定和扩大。对于希望现在做到这一点的人,正确的代码,住在这里:https://github.com/django/django/blob/master/django/core/validators.py#L168-L180

这里是django.core.validators的一部分,您可能会发现有趣的:)

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

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 

,这里是Perl中Mail::RFC822::Address regexp,如果你真的需要是偏执。

+0

谢谢,用email_re(这是整个网络中的代码片段)导入的,但你的第二个代码块做了窍门 – 2012-01-03 21:16:42

+2

这对于即将推出的新顶级域名扩展(超过6个字符的扩展名我认为)是无效的http ://mashable.com/2011/06/21/icann-top-level-domains-change/ – jptsetung 2012-01-23 05:44:21

+0

我相信'email_re'表达式中可能存在一个错误。特别是在引用的字符串行中,我猜测的意图是'\ 001-011'实际上应该是'\ 001- \ 011'。有什么想法吗? – kalefranz 2013-09-10 05:51:50

46

伊克,不,请,不要不要尝试自己验证电子邮件地址。这是人们从来没有做的事情之一。

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

>>> 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.'] 
+9

[这是一个基于此方法的小型Python模块](https://gist.github.com/3683902)。只需使用'isEmailAddressValid(address)'来执行验证。 – 2012-09-09 11:35:15

+0

由于问题是关于Django的,所以这是最好的答案。为了鼓励代码重用和简单性+1。 – 2014-02-09 02:56:48

7

你理解错了,但你不能做反正任务。有一种唯一的方法可以确定RFC 2822地址是否有效,即发送邮件并获得响应。做其他任何事情都不会提高你的数据的信息内容,甚至是一点点。

当你给我validateEmail

[email protected] 

地址也拧人为因素和接受属性,你告诉我,我已经犯了一个错误,我告诉你的应用程序再见。

+0

幸运的是,这个正则表达式不是我的:)所以你也是正常的EmailField方法? – muntu 2010-07-10 03:48:08

+0

我不会说django,但该参数适用于语法验证地址的任何尝试。 http://code.djangoproject.com/ticket/3344看起来甚至没有EmailField可能会达到任务(但我看起来并不真实) – msw 2010-07-10 04:02:13

+0

该特定票证自07/04/07以来被标记为固定,并且在unicode处理翻译的错误信息时出现错误。我认为使用Django验证器现在是相对安全的。 – cji 2010-07-10 07:08:38

0

从该变化开始您的代码:

re.match( '\ B [\ W .-] + @ [\瓦特.-] + \ W {2,4} \湾',电子邮件)

这样:

re.match(R'\ b [\ W .-] + @ [\瓦特.-] + \ W {2,4} \湾',email)

对我很好。

92
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" 
+2

当问题最初被问到时,这个解决方案还没有回来,但绝对是最好的答案。 – keithhackbarth 2015-01-29 19:51:48

+0

仍然是2017年的最佳答案..! 转发至2018 ..!根据目前的流程,这应该是绝对可以接受的答案。 – Jay 2017-12-14 13:12:28

0

这个正则表达式将以合理的准确性验证一个电子邮件地址。

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

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