Regex 如何使用正则表达式验证电子邮件地址?

Regex 如何使用正则表达式验证电子邮件地址?,regex,validation,email,email-validation,string-parsing,Regex,Validation,Email,Email Validation,String Parsing,多年来,我慢慢地开发了一种能够正确验证大多数电子邮件地址的方法,假设它们不使用IP地址作为服务器部分 我在几个PHP程序中使用它,并且大多数时候都能正常工作。然而,有时我会与使用它的网站有问题的人联系,最后我不得不做一些调整。最近我意识到我不允许使用4字符TLD 你见过的验证电子邮件的最好的正则表达式是什么 我见过一些使用函数的解决方案,这些函数使用几个较短的表达式,但我宁愿在一个简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。我使用 ^\w+[-+.]\w+*@\w+

多年来,我慢慢地开发了一种能够正确验证大多数电子邮件地址的方法,假设它们不使用IP地址作为服务器部分

我在几个PHP程序中使用它,并且大多数时候都能正常工作。然而,有时我会与使用它的网站有问题的人联系,最后我不得不做一些调整。最近我意识到我不允许使用4字符TLD

你见过的验证电子邮件的最好的正则表达式是什么

我见过一些使用函数的解决方案,这些函数使用几个较短的表达式,但我宁愿在一个简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。

我使用

^\w+[-+.]\w+*@\w+[-.]\w+*\.\w+[-.]\w+*$
这是RegularExpressionValidator在ASP.NET中使用的地址。

不知道best,但至少是正确的,只要地址的注释被删除并替换为空白


真的。您应该使用已编写的库来验证电子邮件。最好的方法可能是只向该地址发送一封验证电子邮件。

网上有很多这样的例子,我认为即使是一封完全验证RFC的邮件,但如果内存可用,它也有几十行或几百行。人们往往会对这类事情心神不宁。为什么不检查它是否有@和至少一个。满足一些简单的最小长度。输入一封伪造的电子邮件,但仍然匹配任何有效的正则表达式,这很简单。我想,误报比误报好。

我从不费心用自己的正则表达式来创建,因为很可能其他人已经想出了更好的版本。我总是找一个我喜欢的。

因为它很长,所以效率很低,也很模糊。幸运的是,RFC 822被两次取代,当前的电子邮件地址规范是。RFC5322生成了一个正则表达式,如果研究几分钟就可以理解,并且对于实际使用来说足够有效

在页的顶部可以找到一个符合RFC 5322的正则表达式,但它使用的IP地址模式在internet上四处浮动,带有一个错误,允许00代表点分隔地址中的任何无符号字节十进制值,这是非法的。其余部分似乎与RFC5322语法一致,并通过了使用grep-Po的多项测试,包括域名、IP地址、坏域名和带引号和不带引号的帐户名

纠正了IP模式中的00错误,我们得到了一个运行良好且速度相当快的正则表达式。刮取渲染版本,而不是标记,以获取实际代码

[a-a-z0-9-5 5-5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5[a-z0-9]?:[a-z0-9-]*[a-z0-9]?\[?:?:25[0-5]|[0-4][0-9]|[1[0-9][0-9]|[1-9]?[0-9]\.{3}:25[0-5]|[0-4][0-9]|[1[0-9][0-9]|[1-9]?[a-z0 9-][\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]\\[\x01-\x09\x0b\x0c\x0e-\x7f]+\]

或:

下面是对上述regexp的详细说明,它比regexp本身更清楚

Perl和PCRE regex库中使用的更复杂的模式(例如PHP中使用的模式)也可以做到这一点。Python和C也可以做到这一点,但它们使用的语法与前两种不同。然而,如果您被迫使用许多功能较弱的模式匹配语言中的一种,那么最好使用真正的解析器

同样重要的是要了解,根据RFC验证它绝对不会告诉您该地址是否确实存在于提供的域中,或者输入该地址的人是否是它的真正所有者。人们总是以这种方式向其他人注册邮件列表。要解决这一问题,需要一种更奇特的验证,包括es向该地址发送包含确认令牌的消息,该令牌将被输入到与该地址相同的网页上

确认令牌是知道你得到输入者地址的唯一方法。这就是为什么大多数邮件列表现在使用这种机制来确认注册。毕竟,任何人都可以写下president@whitehouse.gov,这甚至会被解析为合法,但不太可能是另一端的人

对于PHP,不应使用中给出的模式,我引用其中的内容:

常见用法和广泛使用的草率编码可能会为电子邮件地址建立一个事实上的标准,该标准比记录的正式标准更具限制性

这并不比所有其他非RFC模式好多少,它甚至不足以处理甚至,更不用说RFC5322了

如果你想变得花哨和迂腐,正则表达式只能充当一个基本的过滤器。正则表达式的问题是告诉某人他们的完美 ly-valid电子邮件地址无效误报,因为您的正则表达式无法处理它。从用户的角度来看,这是粗鲁和不礼貌的。用于此目的的状态引擎可以验证甚至更正电子邮件地址,否则将被视为无效,因为它根据每个RFC分解电子邮件地址。这会带来一种潜在的更愉快的体验,比如

指定的电子邮件地址'myemail@address,com'无效。你是说myemail@address.com”“是吗

另见,包括评论。或者


这完全取决于你想要的准确度。出于我的目的,我只是想在邮件中屏蔽一些东西,比如bob@aol.com空间,或者史蒂夫根本没有域名,或者mary@aolcomcom之前没有句号,我使用

/^\S+@\S+\.\S+$/
当然,它会匹配无效的电子邮件地址,但这是一个获取常见简单错误的问题


可以对该正则表达式进行任意数量的更改,其中一些更改在本答案的注释中,但它简单易懂,是一次很好的首次尝试。

没有一个是真正可用的。 我在我的文章中讨论了一些问题,在


简言之,不要期望一个单一的、可用的正则表达式能够完成正确的工作。最好的正则表达式将验证语法,而不是电子邮件的有效性jhohn@example.com是正确的,但它可能会反弹…

在决定允许使用哪些字符时,请记住您的撇号和连字符朋友。我无法控制我的公司从人力资源系统中使用我的姓名生成我的电子邮件地址。这包括我姓中的撇号。我无法告诉你有多少次我被阻止与网站互动,因为我的电子邮件地址无效

Flickr写了一篇名为的文章,展示了如何进行符合RFC 2822的电子邮件地址解析。你也可以用python和ruby来获取源代码。

这个问题被问了很多,但我认为你应该退一步问问自己,为什么要用语法验证电子邮件地址?真正的好处是什么

它不会捕捉常见的打字错误。 它不阻止人们输入无效或虚构的电子邮件地址,或输入其他人的地址。
如果要验证电子邮件是否正确,您别无选择,只能发送确认电子邮件并让用户回复。在许多情况下,出于安全原因或道德原因,您无论如何都必须发送确认邮件,因此您不能违背某人的意愿注册服务。

我要验证的电子邮件地址将由ASP.NET web应用程序使用System.NET.mail命名空间向人员列表发送电子邮件

因此,我没有使用一些非常复杂的正则表达式,而是尝试从地址创建一个MailAddress实例。如果地址格式不正确,MailAddress构造函数将引发异常。这样,我知道我至少可以把邮件拿到门外。当然这是服务器端验证,但至少您需要这样做

受保护的无效emailValidator_ServerValidateobject源,ServerValidateEventArgs args { 尝试 { var a=新的MailAddresstxtEmail.Text; } 捕获异常 { args.IsValid=false; emailValidator.ErrorMessage=电子邮件:+ex.消息; } }
[更新]我在这里整理了我所知道的关于电子邮件地址验证的所有信息:,它现在不仅可以验证电子邮件地址,还可以诊断电子邮件地址的问题。我同意这里的许多评论,即验证只是答案的一部分;请看我的文章

据我所知,is_电子邮件仍然是唯一一个能够明确告诉您给定字符串是否为有效电子邮件地址的验证器。我已经在上上传了一个新版本

我整理了来自Cal Henderson、Dave Child、Phil Haack、Doug Lovell、RFC5322和RFC 3696的测试用例。总共275个测试地址。我对我能找到的所有免费验证器运行了所有这些测试

当人们增强验证器时,我会尽力使这个页面保持最新。感谢Cal、Michael、Dave、Paul和Phil在编写这些测试中提供的帮助和合作,以及对这些测试的建设性批评


人们尤其应该意识到这一点。其中三个规范示例实际上是无效地址。地址的最大长度是254或256个字符,而不是320个。

这取决于您所说的最佳长度: 如果要捕获每个有效的电子邮件地址,请使用以下方法:

?:?:\r\n?[\t]*?:?:[^@;:\\\.\[\]\000-\031]+?:?:\r\n?[\t] +|\Z |?=[\[@,;:\.\[\]].\124;?:[^\\ r\\].\\\.\124;?::\ r\n?[\t]*?:: \r\n?[\t]*?:\.?:\r\n?[\t]*?:[^@;:\\.\[\]\000-\031]+?:: ?:\r\n?[\t]+\Z |?=[\[@,;:\.\.\[\]].\124;?:[^\\ r\\].\\.\124;?:\ r\n?[ \t] *?:?:\r\n?[\t]***@?:?:\r\n?[\t]*?:[^@,;:\\.\[\]\000-\0 31]+?:?:?:\r\n?[\t]+|\Z |?=[\[@,;:\\\.\[\].\[\].\[\].\[\\].[\\\[^\[\]\r\\\]\\\\\*\ ]?:?:\r\n?[\t]*?:\?::\r\n?[\t]*?:[^@,; :\\.\[\] \000-\031]+ ?:?:?:\r\n?[\t]+\Z |?=[\[@,;:\\.\[\].\[\].\[\].\[^\[\]\r\\\].\.\.\.\] ?:\r\n?[\t]***\124;?:[^@,;:\\.\[\]\ 000-\031]+?:\r\n?[\t]+\Z |?=[\[@,;:\\.\[\]].\124;?:[^\\ r\\].\124\.\ 124;?:\ r\n?[\t]*?:\r\n ?[\t]***\?:?:\r\n?[\t]*.\124;?:[^@,;:\.\[\]\ 000-\031]+?:? :?:\r\n?[\t]+\Z |?=[\[@,;:\.\.\[\]]].\124;?:[^\\ r\\].\\\.\r\n? [\t]*?:?:\r\n?[\t]**:?:?:\r\n?[\t]*?:?:?:?:[^@;:\.\[\] \000-\031]+?:?:\r\n?[\t]+\Z |?=[\[@,;:\\.\[\]]\124;?:[^\\ r\]| \\.|?:?:\r\n?[\t]*?:\r\n?[\t]*?:\.?:\r\n?[\t]*?:[^ @,;:\\.\[\]\000-\031]+?:?:\r\n?[\t]+\\.\Z\?=[\[@,;:\.\[\]]| ?:[^\\r\\]\\.\r\n?[\t]*?:?:\r\n?[\t]**@?:\r\n?[\t] *?:[^@,;:\.\[\]\000-\031]+?:?:?:\r\n?[\t]+\Z;?=[\[@,;:\\ .\[\]\[\\\[\]\r\\]\\.\.\.\.\]?:?:\r\n?[\t]*?:\.?:\r\n?[\t]*? :[^@,;:\.\[\]\000-\031]+?:?:\r\n?[\t]+\Z |?=[\[@,;:\\[ \]]|\[[^\[\]\r\\]\.\.\.\].:?:\r\n?[\t]**.*:[^@,;:\.\[\]\000- \031]+?:?:\r\n?[\t]+\124;\ Z |?=[\[@,;:\\.\.\[\]]\124;?:[^\\ r\\]\124\\| ?:?:\r\n?[\t]*?:\r\n?[\t]***\?:\r\n?[\t]*?:,\s* ?:?:[^@,;:\.\[\]\000-\031]+?:?:?:\r\n?[\t]+\Z?=[\[@,;:\\ .\[\]\\?:[^\\r\\]\\.\r\n?[\t]*?:\r\n?[\t]*?:\r\n?[\t]*?:\: ?:\r\n?[\t]*?:[^@,;:\\.\[\]\000-\031]+?:?:?:\r\n?[\t]+\Z |=[ \[@,;:\\.\[\].[\].[^\\r\\].[\\.\.[\t]*?:\r\n?[\t] ]**@?:?:\r\n?[\t]*?:[^@;:\\.\[\]\000-\031]+?:\r\n?[\t ]+|\Z |?=[\[@,;:\.\[\].\[\].\[\\]\r\\].\.\.\.\.[\]]:?:\r\n?[\t]*? :\.?:?:\r\n?[\t]*?:[^@;:\.\[\]\000-\031]+?:?:\r\n?[\t]+| \Z |?=[\[@,;:\.\[\].\[\].\[\\]\r\\].\.\.\.[\]]:?:\r\n?[\t]** [^@,;:\\.\[\]\000-\031]+?:\r\n?[\t]+\Z |?=[\[@,;:\\[\ ]]|?:[^\\r\\]\\.\r\n?[\t]*?:\r\n?[\t]**?:\r\n?[\t]**\: ?:\r\n?[\t]**?;\s* 如果您正在寻找更简单但可以捕获大多数有效电子邮件地址的邮件,请尝试以下方法:

^[a-zA-Z0-9.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$ 编辑: 从链接:

此正则表达式将只验证删除了任何注释并替换为空白的地址,这是由模块完成的


您可以使用jQuery验证插件使用的一个:

/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i

对于一个生动的演示,下面的monster相当不错,但仍然不能正确识别所有语法上有效的电子邮件地址:它可以识别多达四层的嵌套注释

这是解析器的工作,但即使地址在语法上是有效的,它也可能无法交付。有时你不得不求助于乡下人的方法,嘿,大家,看着我们

// derivative of work with the following copyright and license:
// Copyright (c) 2004 Casey West.  All rights reserved.
// This module is free software; you can redistribute it and/or
// modify it under the same terms as Perl itself.

// see http://search.cpan.org/~cwest/Email-Address-1.80/

private static string gibberish = @"
(?-xism:(?:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(?-xism:(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+
|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<DQ>(?-xism:(?-xism:[
^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D])))+<DQ>(?-xism:(?-xi
sm:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xis
m:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\
s*)+|\s+)*))+)?(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?
-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*<(?-xism:(?-xi
sm:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^(
)\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(
?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))
|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<
>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]
+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))
|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:
(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s
*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?
:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x
0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xi
sm:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*
<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D]
)))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\
]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-x
ism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+
)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:(
?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?
-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s
*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+(
?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism:
\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[
^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)
+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-x
ism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-xi
sm:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:
\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(
?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+
)*\s*\)\s*)+|\s+)*)))>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-
xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\
s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^
\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))|(?-xism:(?-x
ism:(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^
()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*
(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D])
)|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()
<>\[\]:;@\,.<DQ>\s]+(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s
]+)*)(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+)
)|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism
:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\
s*\)\s*))+)*\s*\)\s*)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((
?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\
x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-x
ism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)
*<DQ>(?-xism:(?-xism:[^\\<DQ>])|(?-xism:\\(?-xism:[^\x0A\x0D
])))+<DQ>(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\
\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-
xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)
+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*))\@(?-xism:(?-xism:(?-xism:
(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(
?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[
^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\
s*\)\s*)+|\s+)*(?-xism:[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+
(?:\.[^\x00-\x1F\x7F()<>\[\]:;@\,.<DQ>\s]+)*)(?-xism:(?-xism
:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:
[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+
))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*
)+|\s+)*)|(?-xism:(?-xism:(?-xism:\s*\((?:\s*(?-xism:(?-xism
:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\(
(?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A
\x0D]))|)+)*\s*\)\s*))+)*\s*\)\s*)+|\s+)*\[(?:\s*(?-xism:(?-
xism:[^\[\]\\])|(?-xism:\\(?-xism:[^\x0A\x0D])))+)*\s*\](?-x
ism:(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism
:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:\s*(?-xism:(?-xism:
(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|)+)*\s*\)\s*))
+)*\s*\)\s*)+|\s+)*))))(?-xism:\s*\((?:\s*(?-xism:(?-xism:(?
>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0D]))|(?-xism:\s*\((?:
\s*(?-xism:(?-xism:(?>[^()\\]+))|(?-xism:\\(?-xism:[^\x0A\x0
D]))|)+)*\s*\)\s*))+)*\s*\)\s*)*)"
  .Replace("<DQ>", "\"")
  .Replace("\t", "")
  .Replace(" ", "")
  .Replace("\r", "")
  .Replace("\n", "");

private static Regex mailbox =
  new Regex(gibberish, RegexOptions.ExplicitCapture); 

一个简单的正则表达式至少不会拒绝任何有效的电子邮件地址,它将检查某个内容,然后是@符号,然后是一个句点,至少是2个内容。它不会拒绝任何内容,但在查看规范后,我找不到任何有效和被拒绝的电子邮件

电子邮件=~/.+@[^@]+\.[^@]{2,}$/

RFC 5322标准:

允许点原子本地部分、带引号的字符串本地部分、过时的混合点原子和带引号的字符串本地部分、域名域、IPv4、IPv6和IPv4映射的IPv6地址域文字域,以及嵌套的CFW

'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD'
RFC 5321标准:

允许点原子本地部分、带引号的字符串本地部分、域名域以及IPv4、IPv6和IPv4映射的IPv6地址域文字域

'/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!"?(?>\\\[ -~]|[^"]){65,}"?@)(?>([!#-\'*+\/-9=?^-~-]+)(?>\.(?1))*|"(?>[ !#-\[\]-~]|\\\[ -~])*")@(?!.*[^.]{64,})(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?2)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?3)){7}|(?!(?:.*[a-f0-9][:\]]){8,})((?3)(?>:(?3)){0,6})?::(?4)?))|(?>(?>IPv6:(?>(?3)(?>:(?3)){5}:|(?!(?:.*[a-f0-9]:){6,})(?5)?::(?>((?3)(?>:(?3)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?6)){3}))\])$/iD'
基本:

允许dot atom本地部分和域名域至少需要两个域名标签,TLD限制为2-6个字母字符

"/^(?!.{255,})(?!.{65,}@)([!#-'*+\/-9=?^-~-]+)(?>\.(?1))*@(?!.*[^.]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?\.){1,126}[a-z]{2,6}$/iD"

您不应该使用正则表达式来验证电子邮件地址

而是使用类,如下所示:

try {
    address = new MailAddress(address).Address;
} catch(FormatException) {
    // address is invalid
}
MailAddress类使用BNF解析器完全按照RFC822验证地址

如果计划使用MailAddress验证电子邮件地址,请注意,此方法也接受电子邮件地址的显示名称部分,而这可能不是您想要实现的。例如,它接受以下字符串作为有效电子邮件地址:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
user1@hotmail.com; user2@gmail.com user1@hotmail.com; user2@gmail.com; user3@company.com 用户显示名user3@company.com user4@company.com 在某些情况下,只有字符串的最后一部分被解析为地址;前面的其余部分是显示名称。要获得没有任何显示名称的普通电子邮件地址,可以对照原始字符串检查规范化的地址

bool isValid = false;

try
{
    MailAddress address = new MailAddress(emailAddress);
    isValid = (address.Address == emailAddress);
    // or
    // isValid = string.IsNullOrEmpty(address.DisplayName);
}
catch (FormatException)
{
    // address is invalid
}
此外,在末尾有一个点的地址,如user@company.邮件地址也接受

如果确实要使用正则表达式,请执行以下操作:


在Perl 5.10或更高版本中很容易:

/?定义 ?&邮箱|?&组 名称和地址规格和地址规格 显示名称和角度地址(&D) ?&CFWS?<?&addr\u spec>?&CFWS? 显示名称:?:?&邮箱列表?&CFWS?&D; ?&CFWS? 短语和短语 ?&邮箱:,?&邮箱* ?本地部分\@?域(&U) ?&dot_原子|?"ed_字符串 点原子和域文字 ?&CFWS?\[?:?&FWS???&dcontent*?&FWS? \]?&CFWS? ? ?&dtext |?&引用对 ? ?&否\u WS\u CTL |[\x21-\x5a\x5e-\x7e] ? ?&ALPHA |?&数字|[!\$%&'*+-/=?^ `{124;}] ? ?&CFWS&atext+?&CFWS? ? ?&CFWS&点\原子\文本?&CFWS? ? ?&atext+?:\&atext+* ? [\x01-\x09\x0b\x0c\x0e-\x7f] ? \\ ?&文本 ? ?&否\u WS\u CTL |[\x21\x23-\x5b\x5d-\x7e] ? ?&qtext |?&双引号 ? ?&CFWS&DQUOTE?:&FWS&Q内容* ?&FWS&DQUOTE?&CFWS? ? ?&原子|?&引号_字符串 ? ?&话+ 折叠空白 ? ?: ?&WSP*?&CRLF&WSP+ ? ?&没有\WS\u CTL |[\x21-\x27\x2a-\x5b\x5d-\x7e] ? ?&ctext |?&引用|对|?&注释 ? \ ?: ?&FWS&内容*?&FWS?\ ? ?: ?&FWS&评论* ?:?:&FWS&注释|?&FWS 无空白控制 ? [\x01-\x08\x0b\x0c\x0e-\x1f\x7f] ? [A-Za-z] ? [0-9] ? \x0d\x0a ? ? [\x20\x09] ?&地址/x
更不用说,非拉丁汉语、阿拉伯语、希腊语、希伯来语、西里尔语等域名都是允许进入的。每个人都必须更改使用的电子邮件正则表达式,因为这些字符肯定不在[a-z]/i或\w中。他们都会失败

毕竟,验证电子邮件地址的最佳方法仍然是向相关地址发送电子邮件以验证该地址。如果电子邮件地址是用户身份验证注册/登录/etc的一部分,那么您可以将其与用户激活系统完美结合。即,向指定的电子邮件地址发送带有唯一激活密钥的链接的电子邮件,并且仅当用户使用电子邮件中的链接激活了新创建的帐户时才允许登录

如果正则表达式的目的只是在UI中快速通知用户指定的电子邮件地址格式不正确,那么最好还是检查它是否与以下正则表达式基本匹配:

^([^.@]+)(\.[^.@]+)*@([^.@]+\.)+([^.@]+)$
就这么简单。你究竟为什么要关心名称和域中使用的字符?输入有效的电子邮件地址是客户的责任,而不是服务器的。即使客户端输入语法有效的电子邮件地址,如aa@bb.cc,这并不保证它是合法的电子邮件地址。没有一个正则表达式可以涵盖这一点。

这个正则表达式来自Perl的库。我相信这是最准确的,它匹配所有822。它基于O'Reilly书中的正则表达式:

在中使用Jeffrey Friedl的示例构建正则表达式 掌握正则表达式


有关验证电子邮件地址的最佳正则表达式的最全面的评估,请参阅此链接

以下是当前的top表达式,仅供参考:

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i

根据官方标准,有效的电子邮件regex是

[a-a-z0-9-5 5-5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5[a-z0-9]?:[a-z0-9-]*[a-z0-9]?\[?:?:25[0-5]| 2[0-4][0-9]|[01]?[0-9][0-9]?\{3}:25[0-5]| 2[0-4][0-9]|[01]|[0-9][0-9]?*[a-z0 9]::[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]\\[\x01-\x09\x0b\x0c\x0e-\x7f]+\] 如果你想在Java中使用它,那真的很简单

import java.util.regex.*;

class regexSample 
{
   public static void main(String args[]) 
   {
      //Input the string for validation
      String email = "xyz@hotmail.com";

      //Set the email pattern string
      Pattern p = Pattern.compile(" (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"
              +"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")"
                     + "@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\]");

      //Match the given string with the pattern
      Matcher m = p.matcher(email);

      //check whether match is found 
      boolean matchFound = m.matches();

      if (matchFound)
        System.out.println("Valid Email Id.");
      else
        System.out.println("Invalid Email Id.");
   }
}

这是我使用的PHP。我之所以选择这个解决方案,是因为这里的另一位评论者声称,误报比误报好,而且关于保持响应时间和服务器负载降低……当这将消除最简单的用户错误时,真的没有必要用正则表达式浪费服务器资源或者,如果您愿意,您可以随时通过发送测试电子邮件来跟进

function validateEmail($email) {
  return (bool) stripos($email,'@');
}

当您使用PHP编写时,我建议您对电子邮件使用PHP内置验证

filter_var($value, FILTER_VALIDATE_EMAIL)
如果您运行的php版本低于5.3.6,请注意此问题:

如果您想了解此内置验证如何工作的更多信息,请参见此处:

Per:

^[a-zA-Z0-9.!$%&'*+/=?^ `{124;}-]+@[a-zA-Z0-9]:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]:\[a-zA-Z0-9]:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]*$ 背景:

有效的电子邮件地址是与ABNF产品[…]匹配的字符串

注意:此要求是of,它定义了电子邮件地址的语法,该语法在“@”字符之前过于严格,在“@”字符之后过于模糊,并且过于宽松,允许大多数用户不熟悉的注释、空白字符和引用字符串在此处实际使用

以下兼容JavaScript和Perl的正则表达式是上述定义的实现

/^[a-zA-Z0-9.!$%&'*+/=?^ `{124;}-]+@[a-zA-Z0-9]:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]:\[a-zA-Z0-9]:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9]*$/
如果你可以接受空值,这不是无效的电子邮件 如果您运行的是PHP 5.2+,我建议:

static public function checkEmail($email, $ignore_empty = false) {
        if($ignore_empty && (is_null($email) || $email == ''))
                return true;
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

我已经用了一段时间你的正则表达式的这个润色版本,它没有给我留下太多的惊喜。我从未在电子邮件中遇到过撇号,所以它无法验证这一点。它确实验证了Jean+François@anydomain.museum和试@例子.测试.但不要奇怪地滥用那些非字母数字字符。+@you.com

它确实支持IP地址you@192.168.1.1但我还没有对其进行足够的改进,以处理诸如999.999.999.1之类的伪造IP范围

它还支持超过3个字符的所有TLD,这些字符将停止asdf@asdf.asdf我想这是原版的

我知道acrosman已经放弃了他的regex,但这种味道依然存在。

快速回答 使用以下正则表达式进行输入验证:

[-!-'*+/-9=?A-Z^-~+\.-!-'*+/-9=?A-Z^-~+*.[]-[0-9A-Za-z][0-9A-Za-z-]{0,61}[0-9A-Za-z]?\[0-9A-Za-z][0-9A-Za-z-]{0,61}[0-9A-Za-z]+

此正则表达式匹配的地址:

具有严格符合RFC 5321/5322的本地零件,即@-标志前的零件, 有一个域部分,即@符号后面的部分,它是一个主机名,至少有两个标签,每个标签最多63个字符。 第二个限制是对RFC 5321/5322的限制

详尽的回答 使用识别电子邮件地址的正则表达式在各种情况下都很有用:例如,扫描文档中的电子邮件地址、验证用户输入或作为数据存储库的完整性约束

但是,需要注意的是,如果您想知道该地址是否实际引用了现有邮箱,那么向该地址发送消息是无可替代的。如果您只想检查地址的语法是否正确,则可以使用正则表达式,但请注意,@[]是一个语法正确的电子邮件地址,它肯定不会引用现有邮箱

电子邮件地址的语法有多种定义,最显著的是和。RFC 822应视为原始标准,RFC 5322应视为最新标准。RFC 822中定义的语法是最宽松的,后续标准对语法的限制越来越大,更新的系统或服务应该识别过时的语法,但永远不会生成它

在这个答案中,我将“电子邮件地址”理解为RFCs中定义的地址规范,即。jdoe@example.org,但不是John Doe,也不是某个团体:jdoe@example.org,mrx@exampel.org;.

将RFC语法转换为正则表达式有一个问题:语法不是规则的!这是因为它们允许电子邮件地址中可以无限嵌套的可选注释,而无限嵌套不能用正则表达式描述。要扫描或验证包含注释的地址,您需要一个解析器或更强大的表达式。请注意,像Perl这样的语言具有以类似正则表达式的方式描述上下文无关语法的结构。在这个回答中,我会忽略注释,只考虑适当的正则表达式。

RFC为电子邮件定义语法,而不是电子邮件地址。地址可能出现在各种标题字段中,这是它们的主要定义位置。当它们出现在标题字段中时,地址可能包含词法标记之间的空格、注释甚至换行符。然而,从语义上来说,这没有什么意义。通过删除地址中的空格等,可以得到语义上等价的规范表示。因此,第一类的规范表示。最后一条评论[3.5.7.9]是第一条。最后一条评论[3.5.7.9]

不同的语法应用于不同的目的。如果您想在可能非常旧的文档中扫描电子邮件地址,最好使用RFC 822中定义的语法。另一方面,如果要验证用户输入,可能需要使用RFC 5322中定义的语法,可能只接受规范表示。您应该决定哪种语法适用于您的特定案例

我在这个答案中使用POSIX扩展正则表达式,假设是ASCII兼容字符集

RFC 822 我得到了下面的正则表达式。我邀请每个人尝试打破它。如果您发现任何误报或漏报,请在评论中发布它们,我会尽快修复表达式

目前,除除除以下几几几[[[[目前,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,[目前目前目前目前目前,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,:\\.\x00-\x1F\x7F]+\[\n\\\\\r*[^][\\\r\n]\\[^\r]*\\\r*]*

我相信它完全符合RFC 822,包括。它只识别标准形式的电子邮件地址。对于识别折叠空格的正则表达式,请参见下面的推导

推导过程显示了我是如何得到这个表达式的。我列出了RFC中所有相关的语法规则 ar,后跟相应的正则表达式。在已发布勘误表的地方,我为标记为勘误表的已更正语法规则提供了一个单独的表达式,并将更新版本用作后续正则表达式中的子表达式

如第3.1.4段所述。在RFC 822中,可选的线性空白可以插入词法标记之间。在适用的情况下,我已扩展表达式以适应此规则,并使用opt lwsp标记结果

字符=。它只识别标准形式的电子邮件地址。对于识别折叠空格的正则表达式,请参见下面的推导

推导过程显示了我是如何得到这个表达式的。我列出了RFC中的所有相关语法规则,与它们显示的完全相同,后面是相应的正则表达式。对于包含语义无关的折叠空格的规则,我给出了一个单独的正则表达式,该正则表达式标记为normalized,不接受该空格

我忽略了所有来自RFC的obs规则。这意味着正则表达式只匹配严格符合RFC 5322的电子邮件地址。如果您必须像更宽松的语法(包括obs规则)那样匹配旧地址,那么可以使用上一段中的RFC 822正则表达式之一

VCHAR=%x21-7E =~ [!-~] ALPHA=%x41-5A/%x61-7A =~[A-Za-z] 数字=%x30-39 =~ [0-9] HTAB=%x09 =~\t CR=%x0D =~\r LF=%x0A =~\n SP=%x20 =~ DQUOTE=%x22 =~ CRLF=CRLF =~\r\n WSP=SP/HTAB =~[\t] 引号对=\VCHAR/WSP =~\\[\t-~] FWS=[*WSP CRLF]1*WSP =~[\t]*\r\n?[\t]+ ctext=%d33-39/%d42-91/%d93-126 =~ []!-'*-[^-~] 正则表达式中没有注释 ccontent=ctext/引用对/注释 =~ []!-'*-[^-~]\\[\t-~] 不经常 注释=*[FWS]ccontent[FWS] 当省略注释时,相当于FWS CFWS=1*[FWS]注释[FWS]/FWS =~[\t]*\r\n?[\t]+ atext=ALPHA/数字/!//$/%/&/'/*/+/-/=/?/^//`/{ / | / } / ~ =~[-!-'*+/-9=?A-Z^-~] 点原子文本=1*atext*。1*atext =~[-!-'*+/-9=?A-Z^-~+\.-!-'*+/-9=?A-Z^-~]+* 点原子=[CFWS]点原子文本[CFWS] =~[\t]*\r\n?[\t]+?[-!-'*+/-9=?A-Z^-~+\.-!'*+/-9=?A-Z^-~+*[\t]*\r\n?[\t]+? 标准化=~[-!-'*+/-9=?A-Z^-~]+\.-!-'*+/-9=?A-Z^-~]+* qtext=%d33/%d35-91/%d93-126 =~ []!-[^-~] qcontent=qtext/引用对 =~ []!-[^-~]\\[\t-~] 勘误表 带引号的字符串=[CFWS]DQUOTE 1*[FWS]qcontent[FWS]/FWS-DQUOTE[CFWS] =~[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+?[]-[^-~]\\[\t-~]+[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+? 标准化=~[]-[^-~\t]\\[\t-~]+ dtext=%d33-90/%d94-126 =~[!-Z^-~] 域文字=[CFWS][*[FWS]dtext[FWS]][CFWS] =~[\t]*\r\n?[\t]+?\[\t]*\r\n?[\t]+?[!-Z^-~]*[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+? 标准化=~\[\t-Z^-~]*] 局部部分=点原子/带引号的字符串 =~[\t]*\r\n?[\t]+?[-!-'*+/-9=?A-Z^-~+\.-!'*+/-9=?A-Z^-~+*[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]++?[\t].\r\n-[^-~]\\[\t-~]+[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+? 标准化=~[-!-'*+/-9=?A-Z^-~+\.-!-'*+/-9=?A-Z^-~+*.[]-[^-~\t]\\[\t-~]+ 域=点原子/域文字 =~[\t]*\r\n?[\t]+?[-!-'*+/-9=?A-Z^-~+\.-!'*+/-9=?A-Z^-~+*[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+\[\t]+[\t]*\r\n?[\t]+++++--[\t]*\r\n?[\t]++\r\n? 标准化=~[-!-'*+/-9=?A-Z^-~+\.[-!-'*+/-9=?A-Z^-~+*\[\t-Z^-~*] addr spec=本地部分@域 =~[\t]*\r\n?[\t]+?[-!-'*+/-9=?A-Z^-~+\.-!'*+/-9=?A-Z^-~+*[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]+?[\t]*\r\n?[\t]++?[\t].\r\n-目前,在本月的[3\n\n\\r\n\r\n???\\r\n??\r\n?\r\n?\r\n??\r\n?\\r\n?\\r\n?\\r\n??\\\n?\\\t?\\\t?\\\n?\\n?\\\n?\t?\\t?\\t?\\\n?\\n?\t?\\\t?\\\\\n?\t?\\\\t?\\\\t?\\\\\\\t?\\t?\\\\\\\\\\\\\t?\\\\\n?\\\\\\\\\\\\\\\\\\\\\\\\n?\\\\\\\\\\\\\\\\\\\\\n?\\\\\\n]*[\t]*\r\n?[\t]+?][\t]*\r\n?[\t]+? 标准化=~[-!-'*+/-9=?A-Z^-~+\.-!-'*+/-9=?A-Z^-~+*.[]-[^-~\t]\[\t-~]+@[-!-'*+/-9=?A-Z^-~+\.-!'*+/-9=?A-Z^-~+*\[\t-Z^-~+*.] 请注意,一些消息来源特别声称RFC 5322对本地部分(即@符号之前的部分)过于严格。这是因为…,a…,b和a。不是有效的点原子,但可以用作邮箱名称。但是,RFC允许使用此类本地部件,但必须对其进行报价。所以不是。。b@example.net你应该写 e.a。。b@example.net,这在语义上是等价的

进一步限制 中定义的SMTP进一步限制了一组有效的电子邮件地址或邮箱名称。强制使用这种更严格的语法似乎是合理的,这样匹配的电子邮件地址实际上可以用来发送电子邮件

RFC 5321基本上保留了本地部分,即@符号之前的部分,但对域部分,即@符号之后的部分更为严格。它只允许主机名代替点原子,地址文字代替域文字

当涉及到主机名和IP地址时,RFC5321中提供的语法过于宽松。我冒昧地修改了有问题的规则,使用和作为指导原则。下面是生成的正则表达式

[-!-'*+/-9=?A-Z^-~+\.-!-'*+/-9=?A-Z^-~+*.[]-[0.61}[0-9A-Za-4[0-0-0-0-4[0-0-0-4[0-0-4[0-0-4[0-4-4[0-0-0-9 A-Za-z[0-9A-Za-Za-扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎][0-0-0.0,6[0-0-1}[[0-0-0-0.61}[0-0-0-0-0-9}[0-0-0-9-0-9-0-0-9A-0-0-9-9-9-9-扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎扎(1-9-1-9)1-9[1-1-1-1-9[1-1-9 A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9A-1-9[1-1-1-9[1-1-1-9[1-1-1-1-1-9[1-1-9[1-1-9[1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-9[1[1-1-1-9[1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-1-A-A-f[1-A-Fa-f[1-f[1-f[0[0-f[0-1-1-1-1-1-f[0-1-1-1-1-1-10,3}::{00,3 0 0 0,3 0 0 0 0 0 0,3 3}::::00 0 0 0 0 0 0 0 0,3 0 0 0 0 0 0 0 0 0 0,3 0 0 0 0 0 0 0 0,3 0 0 0 0 0 0 0,3 0 0 0 0 0 0 0 0 0,3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0{0,3}:{0,3}:{0,3}:{0,3}:{0,3}{{00,3}:{0,3}:{0,3}:{00 0,3}:{0 0,3}:{0 0,3}:{0 0 0 0 0,3}::[1-1-9A-A-A-Fa-Fa-f[0-A-A-Fa-f[0-A-A-A-A-A-f[0-A-A-A-f[0-A-A-A-f[0-A-f[0-A-A-A-f[0-A-A-A-f[0-A-A-f[0-A-A-f[0-A-A-f[0-A-A-A-f[0-A-f[0-A-A-A-f[0-A-A-f[0-A-A-f-f::0|[1-9A-A-FAF-f[1-9A-A-FAF-f[1-9A-A-FAF[0-9A-A-f[0-9A-FAF-f[0-9A-9A-A-f-f[1-9A-A-A-f-f[1-9A-A-A-A-f[1-1-1-1-1-9[1-1-1-9 A-A-f[0-9A-A-A-f[0-A-A-f[0-f[0-9A-A-A-f[0-f[0-9A-f[0-9A-A-f[0-A-A-f[0-A-f[0-f[0-9A-A-f-f[0-9A-A-f-f[0-0-9-f-9-f-f[0-9-9-f-9-f-f[[0-9 A-A-Fa-f][0-9 A-A-Fa-f[0-9 A-Fa-f][0-9 A-Fa-f{{0,3}::::::::::::::::::::::::::::::::::::::::0-0-0-9 A-9 A-A-A-Fa-f[0-9 A-A-A-f[0-A-A-f[0-9 A-A-A-A-A-A-f[0-A-A-f[0-A-A-A-f[0-A-A-f[0-A-A-A-f[0-A-f[0-f[0-0-0-0-0-0-0-0-0-0-0-0-9 A-9 A-9 A-A-A-f[0-f[0-f[0-0-0-:[!-Z^-~]+]

请注意,根据使用情况,您可能不希望在正则表达式中允许常规地址文字。还请注意,我在最终正则表达式中使用了负前瞻?!IPv6:以防止常规地址文字部分与格式错误的IPv6地址匹配。某些正则表达式处理器不支持负前瞻。请删除子字符串|?!IPv6:[0-9A-Za-z-]*[0-9A-Za-z]:[!-z^-~]+如果您想删除整个通用地址文字部分,请从正则表达式中删除

以下是推导:

设dig=ALPHA/位 =~[0-9A-Za-z] Ldh str=*阿尔法/数字/-让我们挖 =~[0-9A-Za-z-]*[0-9A-Za-z] 更新正则表达式以确保子域的长度不超过63个字符-RFC 1034第3.5节 子域=Let dig[Ldh str] =~[0-9A-Za-z][0-9A-Za-z-]{0,61}[0-9A-Za-z]? 域=子域*。子域 =~[0-9A-Za-z][0-9A-Za-z-]{0,61}[0-9A-Za-z]?\[0-9A-Za-z][0-9A-Za-z-]{0,61}[0-9A-Za-z]* Snum=1*3数字 =~ [0-9]{1,3} 建议更换Snum ip4八位字节=数字/%x31-39数字/12数字/2%x30-34数字/25%x30-35 =~ 25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9] IPv4地址文字=Snum 3.Snum =~ [0-9]{1,3}\.[0-9]{1,3}{3} 建议替换IPv4地址文字 ip4地址=ip4八位组3.ip4八位组 =~ 25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]\.25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9]{3} 建议更换IPv6 hex ip6-h16=0/%x49-57/%x65-70/%x97-102 0*3%x48-57/%x65-70/%x97-102 =~0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3} 不是来自RFC ls32=ip6-h16:ip6-h16/ip4地址 =~0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}:0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}25[0-5][0-5][2[0-4][0-9][1[0-9]{1[0-9][1-9][1-9]\.25[0-5][0-4][0-4][0-9][1[0-9] 建议更换IPv6地址 ip6地址=6ip6-h16:ls32 /::5ip6-h16:ls32 /[ip6-h16]::4ip6-h16:ls32 /[*1ip6-h16:ip6-h16]::3ip6-h16:ls32 /[*2ip6-h16:ip6-h16]::2ip6-h16:ls32 /[*3ip6-h16:ip6-h16]::ip6-h16:ls32 /[*4ip6-h16:ip6-h16]::ls32 /[*5ip6-h16:ip6-h16]::ip6-h16 /[*6ip6-h16:ip6-h16]: 1-9A-Fa-f[0-9A-Fa-f][0-9A-Fa-f{{0,3}:{6}:::{0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3}:::{00 0 0 0 0 0 0.3}:::::{00 0 0 0 0[0 0 0 0 0 0 0-9A-A-A-f-f-f[0 0-1-1-A-A-f[0-f[0-1-1-9 A-f[0-9 A-f[0-9 A-f[0-9 A-f[0-9 A-A-A-f[0-A-A-f[0-A-A-f[0-9 A-f[0-9 A-A-f[0-A-f[0-9 A-f[0-f[1-9A-Fa-f][0-9A-Fa-Fa-f[0-9A-Fa-f][0-9A-Fa-Fa-f[0-9A-Fa-f][0-9A-Fa-f{0,3}:{0,3}:{0,3}:{0,3}:{0,3}:[0-1-1-9A-A-Fa-f][0-9A-Fa-f[0-Fa-f[0-9A-Fa-f[0.0,3}:{0,3}::::{{0.3}:::{{{{{{00,3}:::::{{{{{{{00 0 0,3}::::::::::::{00 0 0,3.3}::::::::::::{00 0 0 0 0 0.3}::::::::::::::[0-9A-Fa-f]0.3}0 0 0 0 0,3 0 0 0 0 0 0 0 0 0 0 0 3}::{00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0:0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}| 25[0-5]|2[ 4-0-4[0-4[0-4 0 0-4][0-0-4][0-4[0-4 0-4][0-4[0-4[0-4[0-4[0-4[0-9”0-4[0-4[0-0-4[0-0-4[0-9[0-9[0-9[0-9[1[0-9[0 0-9[0-9]1[0 0-9]1[0-3}{{{{0-3[0-3[0-3[3}}{{{1[0-3[0-3}0-3[3}[3}0-3}0-3}[0-3}0-3}0-3}0-3}0-0[0[0-9[0-1-9[0-9[1-1-1-1-1-1-1-1-9[1-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]{0,3}:{0,6}0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}: IPv6地址文字=IPv6:ip6地址 1-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f{{0,3}:{6}}::::::::::{6}6}:::::::::::::[0-1-9A-A-Fa-f[0-9A-A-Fa-f[0-9A-A-f[0-9A-A-A-f[0-A-A-Fa-f[0-f[0-9A-A-A-A-A-A-f[0-A-A-f[0-A-A-f[0-A-A-f[0-9 A-A-A-A-f[0-9A-A-A-f[0-9-A-A-f[0-A-f[0-9A-A-A-A-A-A-f[0-A-f[0-A-A-A-f[1-9A-Fa-f][0-9A-Fa-Fa-f[0-9A-Fa-f][0-9A-Fa-f[0-9A-Fa-f][0-9A-Fa-f[0-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-1-9 A-Fa-f][0-9A-Fa-f[0.0,3}:{0,3}:{0,3}::{00 0,3}::::{{{00,3}::::{{00 0 0 0 0 0 0 0 0 0 0,3}3}::::::::{{{{{00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3:::::::::::::::::{00 0 0 0 0 0 0 0 0[f-Fa-f][0-9A-Fa-Fa-Fa-f[0-9A-Fa-f[0-9A-Fa-f][0-9A-Fa-f[0-0,3}::::0 0-0-0-0-9A-Fa-f[0-0-0-0-0-0-3}:{{0.0.3}::::::::::::::::0(0-1-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-9 A-9 A-9 A-9 A-Fa-Fa-f-f-f-f-f-f-f[0-f-f[0[0[0-0-0-0-0[0-0-0-0-0-0-0-0-0-0-0-0-0[0-3-0 0-5}{0 0 0 0-5 0 0-5 5 5 0 0-5 5 5 0 0 0-5 5 5 0 0 0-5 5 5 0 0 0-5 5 5[0-0-0 0-4 0 0 0-4[0-4 0 0 0-5 5 5 5 5 5 0 0-3)0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}::0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}:{0,6}0 |[1-9A-Fa-f][0-9A-Fa-f]{0,3}: 标准化标记=Ldh str =~[0-9A-Za-z-]*[0-9A-Za-z] 数据内容=%d33-90/%d94-126 =~[!-Z^-~] 一般地址文字=标准化标记:1*d内容 =~[0-9A-Za-z-]*[0-9A-Za-z]:[!-z^-]+ 地址文字=[IPv4地址文字/IPv6地址文字/通用地址文字] [25[0-0-5 5 0 0-0 0 0-5[0 0-5 5 5[0-0 0 0 0 0 0 0-5 5 5[0-0 0 0-5 5 5[0-0 0 0 0-5 5 5 5[0-0 0 0 0 0-5 5 5 5 5[0-0 0 0 0-5 5 5 5[0-0 0-5 5 5 5 5 5 5 5[0-0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5[0 0 0 0 0 0 0 0 0 0 0-5 5 5 5 5 5 5 5 5 5 5 5 5 5 5[0 0 0-5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5[0 0 0 0 0 0 0 0 0 0-5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1-9A-Fa-f[0-9A-Fa-f][0-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9 A-Fa-f[0-9 A-Fa-f][0-5}5 5 5}5 5}5}5 5 5}5 5 5 5 5 5}5 5 5 5 5}5 5 5 5 5 5 5 5 5}5 5}5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5}::::::{5 5 5 5 5 5 5 5}5 5 5 5 5}5 5 5 5 5 5 5 5 5 5 5 5 5}5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5}5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5-9A-Fa-f]{0,3}:[0,3}::::0 0 0 0 0 0,3 0 0 0 0 0 0 0 0,2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,3}:{0,4}{00,0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5]\.25[0-5]| 2[0-0-4 0-0-4][0-0-4][0-0-4][0-0-4][0-0-0 0-4[0-0-0-0-0-0-0-0-0-0-0-0-0-4[0-0-4[0-0-0-4][0-0-0-0[0-0-0[0-0-0-0-0[0-0[0-0-0 0 0-0-0 0 0 0 0 0[0[0 0-0-9]0-9]0 0 0 0 0-0 0 0[0[0-0 0-9]0 0 0 0 0 0 0 0 0 0 0 0 0 0-9]0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0[0 0 0-3]5[0[0[0-0-0-0-3]0[0[0[0-9]0-3]0-3}0[0-3]0,6}0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}?:::|?!IPv6:[0-9A-Za-z-]*[0-9A-Za-z]:[!-z^-~+] 邮箱=本地部分@域/地址文字 目前,这一方面的9月9月9 9月9月9月9月9月9月9月9月9月9月9月9月9日,一个-A--Z的7月7 7月9 9月9 9月9 9 9月9月9 9月9月9月9 9月9月9月9月9月9月9月9月9日9月9月9月9月9日9月9月9月9日,9月9月9 9 9 9日,9月9月5 5 5 5 5 5 5 5 5 5 5月9日,9月9月9月9月9月9日[[[[[[[5-A-A-A-A-A-A-A-AZ-A-AZ-Za-Z-AZ-Za-Z-Za-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z[0-0-0-|[1-9]?[0-9]\.25[0-5]|[0-4][0-9]|[1-9]{2}{1-9]?[0-9]{3}{IPv6:0}[1-9A-Fa-f][0-9A-Fa-f]{0,3}:{6}::0}[1-9A-Fa f][0-9A-Fa f][0-9A-Fa 0}|1-9A-Fa-f[1-9A-Fa-f-f[1-9A-A-Fa-f[1-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[1-9A-Fa-f[0-9A-Fa-f[0,3}:{0.3}:{0 0.3}:{{0.1-1-1-1-1-9 A-A-A-f-Fa-f[1-f-f-f[0-f-f-f-f-f[0-A-Fa-f[0-Fa-f[0-A-f[0-A-Fa-f-f[0-0-f[0-0-0-0-9A-A-A-Fa-f[0-A-f-f[0-A-f[0-A-f-f-A-f[0-A-f-f 1-9A-Fa-Fa-Fa-Fa-Fa-Fa-f[1-9A-Fa-f][0-9A-Fa-Fa-f[0-9A-Fa-Fa-f[0-9A-Fa-Fa-f[0-9A-Fa-f[1-9A-Fa-Fa-f][0.0,3}:::::::0 0 0 0.3}:::{0,3}::{{0,3}:::{{{2}{2}2}2}2}0(2}0}0 0 \\\12455}0}0(2}0}0 0 \\12455 5 5}0 0 \\12455 5 5 5 5 5 5 5 5 5 5 5 5 5 5[f][0-9A-Fa-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-f[0-9A-Fa-Fa-f[0-9 A-Fa-f[0-9A-Fa-f[0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-3}::::::::::::::0 0 0 0-0 0 0 0 0 0 0-1-1-1-1-0[1-124;[1-1-1-1-1-1-1-1-9[1-1-0-0-0-0-1-0-9A-9A-9A-9A-A-Fa-Fa-Fa-Fa-f-Fa-Fa-Fa-Fa-f-f-f-f-f-f-4.0-9[0-9 0 0-9 0 0 0 0-9 7 7 7 7 7 7 7 7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-9 9 9 0 0 0 0 0 0 0 0 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3 3 3}0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}?::|?!IPv6:[0-9A-Za-z-]*[0-9A-Za-z]:[!-z^-~+] 用户输入验证 一个常见的用例是用户输入验证,例如在html表单上。在这种情况下,排除地址文本并要求主机名中至少有两个标签通常是合理的。以上一节中改进的RFC 5321正则表达式为基础,得到的表达式为:

[-!-“*+/-9=?A-Z^-~+\.-!-”*+/-9=?A-Z^-~+*.[!-[^-~\t]\[\t-~]+@[0-9A-Za-Z][0-9A-Za-Z-]{0,61}[0-9A-Za-Z]?\.[0-9A-Za-Z][0-9A-Za-Z-]+

我不建议进一步限制本地部分,例如通过排除带引号的字符串,因为我们不知道某些主机允许使用哪种邮箱名称,例如。。b@example.net甚至是b@example.net.

我也不建议对文字顶级域列表进行显式验证,甚至不建议施加长度限制记住.museum如何使[a-z]{2,4}无效,但如果必须:

[-!-“*+/-9=?A-Z^-~+\.-!-”*+/-9=?A-Z^-~+*.[!-[^-~\t]\[\t-~]+@[0-9A-Za-Z][0-9A-Za-Z-]{0,61}[0-9A-Za-Z]?\.*net | org | com | info |等

如果您决定进行明确的顶级域验证,请确保您的正则表达式保持最新

进一步考虑 当只接受域部分中@符号后的主机名时,上面的正则表达式只接受最多63个字符的标签,这是它们应该接受的 轮胎主机名(包括点)的长度不得超过253个字符。虽然严格地说,这个约束仍然是规则的,但是创建一个包含这个规则的正则表达式是不可行的

另一个考虑因素,特别是在使用正则表达式进行输入验证时,是对用户的反馈。如果用户输入了一个不正确的地址,最好给出比简单的语法错误地址多一点的反馈。对于香草正则表达式,这是不可能的

可以通过解析地址来解决这两个问题。在某些情况下,主机名上的额外长度约束也可以通过使用额外的正则表达式进行检查并将地址与两个表达式匹配来解决

这个答案中没有一个正则表达式是针对性能而优化的。如果性能是一个问题,您应该看看您选择的正则表达式是否以及如何优化。

这是一个用于验证电子邮件地址的简单正则表达式:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
这是故意不符合的

注意:此要求是of,它定义了电子邮件地址的语法,该语法在@字符之前过于严格,在@字符之后过于模糊,并且过于宽松,允许大多数用户不熟悉的注释、空白字符和带引号的字符串在此处实际使用



总长度也可以限制为254个字符。

您说过没有好的正则表达式。这是常规验证还是特定于电子邮件地址验证?@Tomalak:仅适用于电子邮件地址。正如bortzmeyer所说,RFC非常复杂。您提到的linux杂志文章在几个方面是错误的。特别是Lovell显然没有阅读RFC3696的勘误表,并且在RFC的发布版本中重复了一些错误。更多信息:Jeff Atwood在这篇博文中有一个可爱的正则表达式来验证所有有效的电子邮件地址:RFC 822,第6.2.4节。特别明确地允许使用大写字母,但这个答案不允许。也许这个答案的作者有意让他们的正则表达式被不敏感地应用。如果是这样的话,应该在答案的正文中明确说明。据我所知,一些库也是错误的。我模模糊糊地记得PHP PEAR有这样一个bug。该页面底部还有一个免责声明,关于规范中的一些东西。regexp不支持。这是RFC 822规范,不是规范。最终,他说得对,真正验证电子邮件地址的唯一方法是向其发送电子邮件并等待答复。电子邮件地址不匹配foobar@dk这是一个有效且有效的电子邮件地址,尽管大多数邮件服务器可能不会接受它,或者会添加一些内容。@Richard:。包含在\S.JJJ中:是的,它将匹配许多垃圾。它也将匹配&$*$@$0%$和**$。对我来说,我更关心的是抓到像这样奇怪的手指错字mary@aolcom比我完全是垃圾。YMMV.仅用于控制@符号:/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/和另一种常见的打字错误:域名中的两个连续点或用逗号代替点^[^\s@]+@[^\s@.,]+\.+[^\s@.,]{2,}$这是一个很好的分数。即使此服务器验证拒绝了某些有效地址,这也不是问题,因为您无论如何都无法使用此特定服务器技术发送到此地址。或者,您也可以尝试使用任何第三方电子邮件库(而不是默认工具)执行相同的操作。我非常喜欢这种利用.Net framework代码的方式—这对重新发明轮子毫无意义。这太棒了。简单、干净,确保您可以实际发送电子邮件。伟大的作品。。。。是的,对于那些对它如何验证感兴趣的人来说,请看一下Reflector中的代码——其中有很多代码——而且它不是正则表达式!请注意:MailAddress类与RFC5322不匹配,如果您只想将其用于验证而不发送,那么在这种情况下,正如上面提到的,这是一个没有实际意义的点。请参阅:只是一个小问题:如果您想使服务器端验证程序代码在这种情况下或一般情况下更易于重用,我建议使用args.Value,而不是引用txtEmail.Text硬编码之类的字段。后一种方法将您的验证器绑定到单个控件实例,只要您有一个电子邮件字段就可以了,但不建议使用其他方法something@something进入客户端验证领域只是为了抓住简单的错误-但总的来说你是对的。Martin,我给了你+1,只是后来读到的foobar@dk是一封有效的电子邮件。这可能不太好,但如果你想既符合RFC又符合常识,你应该检测这样的情况,并要求用户确认这是正确的。@olavk:如果有人输入错误,例如:me@hotmail,他们显然不会收到你的确认电子邮件,那么他们在哪里?他们已经不在你的网站上了,他们想知道为什么他们不能注册。事实上,他们没有——他们已经完全忘记你了。但是,如果你

你可以在正则表达式还在你身边的时候,用正则表达式做一个基本的健全性检查,然后他们就可以马上发现错误,你就有了一个快乐的用户。@JacquesB:你说得很好。仅仅因为它通过了RFC的审查,并不意味着它就是那个用户的地址。否则所有这些president@whitehouse.gov地址表明他是一位非常内行的总司令:它不必是黑色或白色的。如果电子邮件看起来有误,请让用户知道这一点。如果用户仍想继续,请让他继续。不要强迫用户遵守您的正则表达式,而是使用正则表达式作为工具来帮助用户知道可能存在错误。您会发现.NET 4.0中的MailAddress类在验证电子邮件地址方面比以前的版本要好得多。我对它做了一些重大改进。我认为它有点。。。不起作用。。。对于更简单的ID。a@b无法验证。ar@b.com只匹配到ar@b,则.com不匹配。但是,像我是我这样的东西(10.10.10.10)确实管用:请注意,这些RFC兼容的正则表达式验证器将允许通过许多您可能不想接受的电子邮件地址,例如a@MatthewLock:这并不比fake@not-一个真实的域名。您不能依靠电子邮件验证来阻止XSS。@MatthewLock:不。您需要转义SQL查询,或者最好使用参数。卫生处理不是一种适当的防御。我同意发送身份验证消息通常是这类东西的最佳方式,语法正确和有效并不相同。当我被要求输入两次我的电子邮件地址进行确认时,我会感到沮丧,好像我看不到我输入的内容一样。不管怎样,我只把第一个复制到第二个,它似乎越来越被使用了。同意!但我认为这个正则表达式无效,因为它允许@后面有空格。如。test@test.caCOM Net通过使用上面的正则表达式来考虑一个有效的电子邮件,因为它应该返回无效。你能给我一个错误的电子邮件地址的例子吗?错误地通过第二个,但是被更长的正则表达式所捕获?虽然我曾经很喜欢它,但是它是RFC 822验证程序,一个也没有。@Lazer在。。valid@example.com这将是一个简单的例子。不允许在本地部分有两个连续的不带引号的点。@Mikhail perl,但您不应该实际使用它。@RSC这是一个FQDN,很好,似乎也是正确的。[…时间流逝…]嗯,看起来只是RFC 5322,而不是3693或勘误表。非常好。在这里,我们不仅可以得到一篇好文章,还可以得到一个验证测试员和一个下载库。回答得好!您的验证器不支持punycode RFC 3492。name@öäü.at可以是有效地址。也就是说name@xn-4ca9at.atHi@Josef。您应该尝试验证name@xn-4ca9at.at,因为此代码是关于验证的,而不是解释的。如果您想添加punycode翻译器,那么我很乐意接受pull请求,是的,但是哪个RFC?:此[RFC-5322–验证器]只有大约四十行长。A。不需要。TLD可以有电子邮件地址,也可以有IPv6地址RFCS并不是故事的结尾:ICANN不再允许“无点”域名:这是程序中的一个超级常见问题,这些程序对个人姓名中的哪些内容是允许的,哪些是不允许的。人们不应该做出这样的假设,只要接受相关RFC所说的必须接受的任何字符即可。是的。我对程序员拒绝在电子邮件地址中使用大写字母感到特别愤怒!愚蠢和/或懒惰。如果我错了,请纠正我,但我相信PHP使用PCRE模式。如果是这样的话,您应该能够制作类似于的东西。@tchrist:不确定PCRE是否掌握了我发现的这种语法。如果是这样,不确定PHP的PCRE是否赶上了这个版本的PCRE。。。好吧,如果我正确理解了这个语法,你也可以使用一个PEG解析器,它比正则表达式更清晰、更完整。PCRE已经赶上了它,但也许PHP还没有赶上PCRE。☹调羹16:那个链接不是很正确。它声称不可能有完美的模式来验证电子邮件地址,这显然是错误的。你可以,但是你必须确保你完全按照RFC来做。而且你也必须选择正确的RFC。现在最好的方法不适用于java正则表达式——即使在正确转义和转换字符串之后也是如此。那是什么鬼语言??我看到a/D标志,你用单引号引用了它,还用斜杠来分隔模式?它不是Perl,也不可能是PCRE。这是PHP吗?我相信只有这三个允许像?1这样的递归。它在PHP中使用PCRE。斜杠仅用于分隔特殊字符,如括号、方括号,当然还有斜杠和单引号。如果您不知道,那么/D标志是防止在字符串末尾添加换行符,否则是允许的。Boo!我不明智的地址@mydomain.net被拒绝。根据此页面,没有

顶级中只有一个字符的域,例如something.c、something.a,以下是至少支持两个字符的版本:something.pl、something.us:^\\w++[-.]\\w++*@\\w++[-.]\\w+*\.\\w{2,}[-.]\\w+*$@Wayne Whitty。您遇到了一个主要问题,即是否要满足绝大多数地址或所有地址的需求,包括除了测试电子邮件验证之外没有人会使用的地址。@tomaszzulc您的答案中的额外反斜杠很混乱,我刚刚更正了它,2个字符域名支持正在工作,^\w+[-+.]\w+*@\w+[-.]\w+*\.\w{2,}[-.]\w+*$这在simon--@hotmail.com上失败,事实上这是有效的。我们的一位客户有一个类似的地址“这就是我要找的”。不是很严格,但要确保在解析列表时只有1个@,并确保没有丢失逗号。仅供参考,你可以在左边有一个@,如果它在引号里:,但它是非常边缘化的。使用它后,意识到它完全不起作用/^[^@]+@[^@]+\.[^@]{2}[^@]*$/实际上检查1@符号。您的正则表达式将允许多次通过,因为结尾处有。*。对。我并不是要拒绝所有无效的电子邮件地址,只是要避免拒绝有效的电子邮件地址。最好使用:/^[^@]+@[^@]+\.[^@]+\.[^@]{2,4}$/确保它以2到4个非@字符结尾。正如@Josh所指出的,它现在允许在最后增加一个@。但您也可以将其更改为:/^[^@]+@[^@]+\.[^a-z-a-z]{2,4}$/因为所有顶级域都是a-z字符。您可以用5个或更多的域名替换4个,这样顶级域名将来也可以更长。@FLY,ka@foo. 返回正确值。根据标准,它应该是吗?我希望在Python中看到这一点。我认为只有addrspec部分的一个子集与这个问题真正相关。接受更多,并转发它,尽管系统的其他部分还没有准备好接受完整的RFC5822地址,这就像射击是你自己的脚。很好+1,但从技术上讲,它当然不是正则表达式。。。这是不可能的,因为语法是不规则的。regex在一段时间前就不再是规则的了。但它是一个有效的Perl“regex”!我在IDEone上为这个正则表达式设置了一个测试:然而,它并不完全公平。有人愿意插话吗?我错过了什么吗?得到了投票,这正是我要说的。不处理IDN,但事先转换为微不足道的代码可以解决这个问题。PHP>=5.3对此具有idn到ascii。验证电子邮件的最佳和最简单的方法之一。a浪费的服务器资源非常少,但如果您愿意,您可以使用JS在客户端执行此操作。b您需要发送注册邮件并由用户输入什么me@forgotthedotcom ? 您的解决方案失败,您将失去一个用户。如果禁用JavaScript,依赖JS验证将失败,这听起来也不是最好的主意。这很有趣。这是对RFC的违反,但这是一种故意的行为,它会使sesne。现实世界的例子:gmail忽略@之前部分的点,所以如果你的电子邮件是test@gmail.com你可以发送电子邮件到test.@gmail.com或test.@gmail.com,根据RFC,这两个地址都是无效的,但在现实世界中是有效的。我认为最后一部分应该是“+”而不是“*”:^[a-zA-Z0-9.!$%&'*+/=?^{124}-]+@[a-zA-Z0-9-]+.\[a-zA-Z0-9-]++$@mmmmmm约翰。doe@localhost这是有效的。当然,在现实世界的应用程序中,即社区中,我希望您建议用+@valentinas替换*实际上,RFC并不排除这些本地部分,但它们必须被引用。根据RFC,test..@gmail.com完全有效,在语义上等同于test..@gmail.com。如果我试图发送到带有@或..@的地址,则尝试使用python通过我公司的中继发送电子邮件时出错。事实上,a的情况也是如此。我宁愿在发送之前删除它们,也不相信收件人会这么做。O_O你还需要是一个正则表达式大师才能理解它在做什么。正则表达式匹配MIME语法的部分,如折叠空格和注释;它还允许不允许使用的控制字符a@b是valid@dsdsdsdsd因为a@b是有效的。。。在本例中,b是顶级域。这似乎做得很好。它允许:a-b'c\d。e@f-g、 但是能够捕捉到不适当的变化,例如a-b'cúd。@f-g.h和a-b'cúd。e@f-.hRFC更新允许并包括完整、干净的UTF-8。附加细节。根据维基百科的说法,局部部分(虚线部分)每个部分有64个字符的限制,RFC 5322也指的是要在域限制下解释的虚线部分。例如,arbitral-long-email-address-should-be-invalid-arbitral-long-email-address-should-be-invalid.and-the-second-group-allow-should-not-be-so-long-and-the-second-group-allow-should-not-be-so-long@example.com不应验证。我建议将第一组名称中的+符号改为可选点之前的+符号,并将第二组名称中的+符号改为followin之后的+符号
g点到{1,64}由于注释的大小有限,下面是我计划使用的结果正则表达式,这是本答案开头的一个,加上限制局部部分的大小,再加上根据PHP和regex101.com的要求在/symbol之前添加反斜杠:在PHP中,我使用:$emailRegex='/^[-!-\'*+\/-9=?a-Z^-~]{1,64}。[-!-\'*+\/-9=?A-Z^-~{1,64}*.[]!-[^-~\t]\[\t-~]+@[0-9A-Za-Z][0-9A-Za-Z-]{0,61}[0-9A-Za-Z]?\[0-9A-Za-Z][0-9A-Za-Z-]{0,61}[0-9A-Za-Z]?+$/';警告:出于某种原因,StackOverflow在从渲染标记复制时会添加隐藏字符。将其复制到regex101.com中,您将在那里看到黑点。您必须删除它们并更正字符串…如果在答案中集成,则它们可以正确复制。很抱歉给您带来不便。我不想添加新的标记nswer,因为这是正确的答案。此外,我不想直接编辑,除非社区认为这应该集成到其中。@XaviMontero Thaks,感谢贡献Xavi!您是否参考RFC,说明本地零件标签上的64个字符限制?如果是,我很乐意调整答案。可以验证IDNA是c的正则表达式格式不正确不适合stackexchange。规范化规则非常复杂,特别不适合正则表达式处理为什么不应该这样做:正则表达式可能是可变的,因为在某些情况下,电子邮件con可以包含空格,而在其他情况下,它不能包含任何空格。@Jasen幸运的是,没有要求hat电子邮件地址必须具有有效的IDNA。这样定义电子邮件地址是为了转发与IDNA语法扩展的兼容性。您可以检查Symfonys正则表达式是否松散和严格检查:最佳答案!这里有一个指向w3建议的链接:此正则表达式被许多浏览器采用。这不是最佳答案!此模式匹配此地址完全无效:invalid@emailaddress.我希望在你使用它之前要谨慎和多做测试!@Sheridan,如果你认为HTML5规范有问题,你可以在这里提出一个问题:这不会增加太多内容,作为一个编辑或评论会更好吗。example@localhost是有效的,但对于实际应用程序可能想要强制实施域扩展,您只需将最终*更改为a+,即可实现此目的,将模式的部分从0+更改为1+,这已标记长度和内容,但这仍然是一个很好的贡献,有41票,不应删除。您的正则表达式不包括第一个大写字母,例如Leonardo。davinci@gm该网站可能会对一些用户造成一些烦人的一些用户。使用该网站。改用该网站。该网站可能会对一些用户造成一些烦人的一些用户。该网站可能会对一些用户的一些用户造成一些烦人。该网站可能会对一些用户造成一些烦人。使用该网站。改用该网站:::::::::::::[A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-Za-A-Za-Za-Za-Za-A-Za-A-Za-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A 9-]*[A-z0-9]?\.+[A-z0-9]?:[A-z0-9-]*[A-z0-9]?\[?:?:25[0-5]| 2[0-4][0-9]|[01]|[0-9][0-9]|{3}:25[0-5]| 2[0-4][0-9]|[01]?[0-9][0-9]?[a-z0-9-]*[a-z0-9]:?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]\\[\x01-\x09\x0b\x0c\x0e-\x7f]+]@Kebabkraby谢谢,请编辑答案,我会接受更改。如果我将该更改添加到您的答案中,它将不再是RFC 2822,因此我不知道这是否正确。@Kebabkraby:我想我们需要在匹配选项中的某个地方应用不区分大小写的模式,而不是更改正则表达式本身。
static public function checkEmail($email, $ignore_empty = false) {
        if($ignore_empty && (is_null($email) || $email == ''))
                return true;
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }
(?!^[.+&'_-]*@.*$)(^[_\w\d+&'-]+(\.[_\w\d+&'-]*)*@[\w\d-]+(\.[\w\d-]+)*\.(([\d]{1,3})|([\w]{2,}))$)
/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/