【问题标题】:Checking validity of email in django/python [duplicate]在 django/python 中检查电子邮件的有效性 [重复]
【发布时间】:2011-03-14 03:49:46
【问题描述】:

我编写了一个将电子邮件添加到时事通讯库的函数。在我添加检查已发送电子邮件的有效性之前,它工作得完美无缺。现在每次我收到“错误的电子邮件”作为回报。任何人都可以在这里看到任何错误吗?使用的正则表达式是:

\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

【问题讨论】:

  • 100% 有效?不匹配 foo+bar@example.com,不匹配 foo@museum.com,还有更多。
  • 100% 有效?您的正则表达式将匹配 a..@..............a
  • 实际上@Kos @Zenadix ...你们俩都错了\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b 正则表达式。我刚刚对其进行了测试,结果与你们所说的相反。

标签: python regex django validation email


【解决方案1】:

2017 年更新:下面的代码已有 7 年的历史,此后经过修改、修复和扩展。对于现在希望执行此操作的任何人,正确的代码位于 here 周围。

这是 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,如果你真的需要那么偏执的话。

【讨论】:

  • 谢谢,使用 email_re 进行了导入(这是网络上的 sn-p),但您的第二个代码块成功了
  • 这对于即将推出的新顶级域扩展不再有效(我认为扩展超过 6 个字符)mashable.com/2011/06/21/icann-top-level-domains-change
  • 我相信email_re 表达式中可能存在错误。特别是在引用的字符串行中,我猜测其意图是\001-011 实际上应该是\001-\011。有什么想法吗?
  • 确实,上面的代码有错别字。 github 上的源代码已得到修复:github.com/django/django/blob/master/django/core/validators.py 向那些复制和粘贴该正则表达式的人发出公平警告。
  • 更新部分是最好的部分。 :D
【解决方案2】:

哎呀,不,请不要尝试自己验证电子邮件地址。这是人们永远不会做对的事情之一。

由于您已经在使用 Django,因此最安全的选择是利用其电子邮件表单验证。根据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.']

【讨论】:

  • Here is a tiny Python module based on this method。只需使用isEmailAddressValid(address) 来执行验证。
  • 因为问题是关于 Django 的,所以这是最好的答案。 +1 鼓励代码重用和简单性。
  • 简单胜于复杂,很好的解释
【解决方案3】:
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")

【讨论】:

  • 最初提出问题时,此解决方案不可用,但绝对是最佳答案。
  • 仍然是 2017 年的最佳答案..!前进到2018..!根据当前的流,这应该是绝对接受的答案。
  • 2018 年和 2019 年的最佳答案。前进到 2020..
  • as e 在这里并不真正需要,除非您打算使用 e
【解决方案4】:

我可以在这里看到很多答案都是基于 python 的 django 框架。但是为了验证电子邮件地址,为什么要安装如此繁重的软件。我们有用于 Python 的 Validate_email 包,用于检查电子邮件是否有效、格式正确以及是否真的存在。它是一个轻量级的包(大小

安装:

pip install validate_email

基本用法:

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

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

要检查域 mx 并验证电子邮件是否存在,您可以安装 pyDNS 包和 validate_email。

验证电子邮件是否存在:

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

如果电子邮件存在于现实世界中,则返回 True,否则返回 False。

【讨论】:

  • 我相信这不适用于 python 3,仅适用于 python 2。
【解决方案5】:

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

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

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

【讨论】:

    【解决方案6】:

    从此更改您的代码:

    re.match('\b[\w.-]+@[\w.-]+.\w{2,4}\b', 电子邮件)

    到这里:

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

    对我很好。

    【讨论】:

      【解决方案7】:

      您弄错了,但这是您无论如何都无法完成的任务。只有一种方法可以知道RFC 2822 地址是否有效,那就是向它发送邮件并获得回复。做任何其他事情都不会改善你的数据的信息内容,哪怕只有一点点。

      你还搞砸了人为因素和接受属性,因为当你给validateEmail我的地址时

      me+valid@mydomain.example.net
      

      你告诉我我犯了一个错误,我告诉你的应用程序再见。

      【讨论】:

      • 幸运的是这个正则表达式不是我的 :) 所以你也适合普通的 EmailField 方法?
      • 我不会说 django,但该论点适用于任何试图在语法上验证地址的尝试。 code.djangoproject.com/ticket/3344 看起来甚至 EmailField 都不能胜任这项任务(但我看起来并不努力)
      • 自 2007 年 7 月 4 日起,该特定票证被标记为已修复,并且在翻译错误消息的 unicode 处理中存在错误。我认为现在使用 Django 验证器是相对安全的。
      猜你喜欢
      • 1970-01-01
      • 2019-04-18
      • 2018-09-09
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2011-10-07
      相关资源
      最近更新 更多