234

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

4

18 回答 18

315

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

因此,最基本的检查(例如,他们没有意外输入他们的街道地址)通常就足够了。类似于:它只有一个符号,并且在:之后的部分@中至少有一个符号.@

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

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

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


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

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 服务器联系以验证地址是否存在。但是,这仍然不能保证它属于正确的人。

于 2011-11-05T19:12:34.613 回答
151

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 和朋友的有效电子邮件地址的东西,包括许多在广泛的 Internet 上显然无法寻址的东西:

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

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

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

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

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

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

>>> 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是一个语法有效的地址。仅@应考虑最后一个来检测域部分的开始位置。

于 2013-01-23T17:34:09.533 回答
83

在自定义正则表达式答案的混乱中,我还没有在这里看到答案,但是......

存在一个名为py3-validate-email validate_email的 python 库,它具有 3 级电子邮件验证,包括询问有效的 SMTP 服务器是否电子邮件地址有效(不发送电子邮件)。

安装

python -m pip install py3-validate-email

基本用法:

from validate_email import validate_email
is_valid = validate_email(email_address='example@example.com', \
    check_regex=True, check_mx=True, \
    from_address='my@from.addr.ess', helo_host='my.host.name', \ 
    smtp_timeout=10, dns_timeout=10, use_blacklist=True)

对于那些对肮脏细节感兴趣的人,validate_email.py(source)旨在忠实于RFC 2822

我们真正要做的就是将输入字符串与一个巨大的正则表达式进行比较。但是,通过从 RFC 定义的“令牌”组装它,构建该正则表达式并确保其正确性变得更加容易。这些令牌中的每一个都在随附的单元测试文件中进行了测试。


可能需要 pyDNS 模块来检查 SMTP 服务器

pip install pyDNS

或来自 Ubuntu

apt-get install python3-dns
于 2015-03-11T09:03:03.663 回答
23

电子邮件地址并不像看起来那么简单!例如,Bob_O'Reilly+tag@example.com 是一个有效的电子邮件地址。

我对 lepl 包(http://www.acooke.org/lepl/)有一些运气。它可以验证 RFC 3696 中所示的电子邮件地址:http: //www.faqs.org/rfcs/rfc3696.html

找到一些旧代码:

import lepl.apps.rfc3696
email_validator = lepl.apps.rfc3696.Email()
if not email_validator("email@example.com"):
    print "Invalid email"
于 2011-11-05T19:30:52.367 回答
15

我找到了一种检查有效电子邮件地址的出色(且经过测试)方法。我在这里粘贴我的代码:

# here i import the module that implements regular expressions
import re
# here is my function to check for valid email address
def test_email(your_pattern):
pattern = re.compile(your_pattern)
# here is an example list of email to check it at the end
emails = ["john@example.com", "python-list@python.org", "wha.t.`1an?ug{}ly@email.com"]
for email in emails:
    if not re.match(pattern, email):
        print "You failed to match %s" % (email)
    elif not your_pattern:
        print "Forgot to enter a pattern!"
    else:
        print "Pass"
# my pattern that is passed as argument in my function is here!
pattern = r"\"?([-a-zA-Z0-9.`?{}]+@\w+\.\w+)\"?"   
# here i test my function passing my pattern
test_email(pattern)
于 2016-12-06T11:26:48.837 回答
10

我在这里看到很多复杂的答案。他们中的一些人不知道简单、真实的电子邮件地址,或者有误报。下面是测试字符串是否为有效电子邮件的最简单方法。它针对 2 和 3 个字母的 TLD 进行测试。现在您在技术上可以拥有更大的,您可能希望将 3 增加到 4、5 甚至 10。

import re
def valid_email(email):
  return bool(re.search(r"^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$", email))
于 2017-05-12T12:23:32.810 回答
7
from validate_email import validate_email
is_valid = validate_email('example@example.com',verify=True)
print(bool(is_valid))

请参阅validate_email 文档

于 2018-03-25T08:44:58.827 回答
5

这通常使用正则表达式解决。然而,解决方案有很多变化。取决于您需要的严格程度,以及您是否有自定义验证要求,或者是否接受任何有效的电子邮件地址。

请参阅此页面以供参考:http ://www.regular-expressions.info/email.html

于 2011-11-05T19:09:00.667 回答
4

电子邮件地址非常复杂。这是一个匹配每个 RFC822 有效地址的示例正则表达式: http ://www.ex-parrot.com/pdw/Mail-RFC822-Address.html

您会注意到它可能比程序的其余部分要长。Perl 甚至还有用于验证电子邮件地址的完整模块。所以你可能不会得到任何 100% 完美的正则表达式,同时也是可读的。这是一个递归下降解析器示例: http ://cpansearch.perl.org/src/ABIGAIL/RFC-RFC822-Address-2009110702/lib/RFC/RFC822/Address.pm

但是您需要决定是否需要完美的解析或简单的代码。

于 2011-11-05T19:09:44.113 回答
4
import re
def email():
    email = raw_input("enter the mail address::")
     match = re.search(r'[\w.-]+@[\w.-]+.\w+', email)

    if match:
        print "valid email :::", match.group()
    else:
        print "not valid:::"

email()
于 2014-08-13T16:55:01.640 回答
2

如果你想从一个长字符串或文件中取出邮件然后试试这个。

([^@|\s]+@[^@]+\.[^@|\s]+)

请注意,当您的电子邮件地址前后有空格时,这将起作用。如果您没有空间或有一些特殊字符,那么您可以尝试修改它。

工作示例:

string="Hello ABCD, here is my mail id example@me.com "
res = re.search("([^@|\s]+@[^@]+\.[^@|\s]+)",string,re.I)
res.group(1)

example@me.com这将从该字符串中取出。

另外,请注意这可能不是正确的答案......但我在这里发布它是为了帮助像我这样有特定要求的人

于 2014-11-05T08:15:13.510 回答
1

检查电子邮件使用email_validator

from email_validator import validate_email, EmailNotValidError

def check_email(email):
    try:
        v = validate_email(email)  # validate and get info
        email = v["email"]  # replace with normalized form
        print("True")
    except EmailNotValidError as e:
        # email is not valid, exception message is human-readable
        print(str(e))

check_email("test@gmailcom")
于 2018-01-10T19:42:52.010 回答
0
"^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$"
于 2015-02-11T00:12:43.653 回答
0

在电子邮件输入上使用此过滤器掩码:emailMask: /[\w.\-@'"!#$%&'*+/=?^_{|}~]/i`

于 2019-02-12T20:59:26.063 回答
-1

查找电子邮件 ID: 寻找IP截图

import re 
a=open("aa.txt","r")
#c=a.readlines() 
b=a.read()
c=b.split("\n")
print(c)
  for d in c: 
    obj=re.search(r'[\w.]+\@[\w.]+',d)
    if obj:
      print(obj.group())  
#for more calcification click on image above..
于 2017-08-09T11:24:26.753 回答
-1

发现这是一个实际的实现:

[^@\s]+@[^@\s]+\.[^@\s]+
于 2018-09-12T02:28:10.180 回答
-3

电子邮件验证

import re
def validate(email): 
    match=re.search(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+\.[a-zA-Z0-9.]*\.*[com|org|edu]{3}$)",email)
    if match:
        return 'Valid email.'
    else:
        return 'Invalid email.'
于 2016-10-21T11:25:56.973 回答
-4

区分真实有效电子邮件地址和无效电子邮件地址的唯一真正准确方法是向其发送邮件。算作电子邮件的内容令人惊讶地令人费解("John Doe" <john.doe@example.com>"实际上是一个有效的电子邮件地址),您很可能希望该电子邮件地址稍后实际向其发送邮件。在它通过一些基本的健全性检查之后(例如在 Thomas 的回答中,在之后有一个@和至少一个),您可能应该只向该地址发送一封电子邮件验证信,然后等待用户点击消息中嵌入的链接确认电子邮件有效。.@

于 2011-11-05T19:28:02.007 回答