如何检查有效的电子邮件地址?

新手上路,请多包涵

有没有一种使用正则表达式检查表单输入以确保它是正确样式的电子邮件地址的好方法?自昨晚以来一直在搜索,如果它是子域电子邮件地址,那么回答了人们有关此主题的问题的每个人似乎也有问题。

原文由 Bobby 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 756
2 个回答

无关紧要。即使您可以验证电子邮件地址在语法上是有效的,您仍然需要检查它是否没有输入错误,并且它实际上是发送给您认为的人。做到这一点的唯一方法是向他们发送电子邮件并让他们单击链接进行验证。

因此,最基本的检查(例如,他们没有意外输入他们的街道地址)通常就足够了。类似的东西:它恰好有一个 @ 符号,并且在 . @

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

您可能还想禁止空格 - 可能存在包含空格的有效电子邮件地址,但我从未见过,所以这是用户错误的可能性在您这边。

如果您想要完整检查,请查看 此问题


更新:以下是使用任何此类正则表达式的方法:

 import re

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

Python ≥3.4 有 re.fullmatch 优于 re.match

注意字符串前面的 r ;这样,您就不需要两次逃脱。

如果要检查大量正则表达式,则首先编译正则表达式可能会更快:

 import re

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

if not EMAIL_REGEX.match(email):
  # whatever


另一种选择是使用 validate_email 包,它实际上会联系 SMTP 服务器以验证地址是否存在。但是,这仍然不能保证它属于正确的人。

原文由 Thomas 发布,翻译遵循 CC BY-SA 4.0 许可协议

Python 标准库自带邮件解析函数: email.utils.parseaddr()

它返回一个二元组,其中包含电子邮件的真实姓名和实际地址部分:

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

如果解析不成功,它返回一个空字符串的二元组:

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

这个解析器的一个问题是它接受任何被认为是 RFC-822 和朋友的有效电子邮件地址的东西,包括许多在广泛的互联网上显然无法寻址的东西:

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

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

因此,正如@TokenMacGuy 所说,检查电子邮件地址的唯一确定方法是向预期地址发送电子邮件并等待用户根据邮件中的信息采取行动。

但是,您可能希望至少检查第二个元组元素上是否存在 @-sign,正如@bvukelic 建议的那样:

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

如果你想更进一步,你可以安装 dnspython 项目并解析电子邮件域的邮件服务器(’@’ 之后的部分),只有在实际存在时才尝试发送电子邮件 MX 服务器:

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

您可以同时捕获 NoAnswerNXDOMAIN 通过捕获 dns.exception.DNSException

是的, foo@bar@google.com 是语法上有效的地址。仅应考虑最后一个 @ 来检测域部分的开始位置。

原文由 LeoRochael 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题