php - 使用正则表达式来验证电子邮件地址

  显示原文与译文双语对照的内容

多年以来,我慢慢开发了一个正则表达式,它验证大多数电子邮件地址,假设它们不使用一个IP地址作为服务器部件。

我在几个PHP程序中使用它,它大部分时间都在运行。 然而,我经常遇到一个使用它的网站遇到问题,我最终不得不做一些调整。

你在验证电子邮件时遇到的最佳正则表达式是什么?

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

时间:

这里问题没有简单的正则表达式: (这是之前写的语法模式。)中指定的语法 RFC 5322对原始 正规表达式 太复杂了。

pcre,更复杂的语法模式在perl和php可以管理正确解析rfc 5322顺利 。 python 和 C# 也应该能够管理它,但是它们使用了与前三个相同的语法。 然而,如果你不得不使用一个不那么强大的pattern-matching语言,那么最好使用真正的解析器。

同样重要的是要理解,验证每个rfc告诉你绝对不知道这个地址是否存在于所提供的领域,或者输入地址的人是真正的所有者。 人们总是用这种方式给别人签名。 修复,需要一种更好的验证,包括发送地址信息,包括确认标记意味着输入相同的网页地址。

确认令牌是唯一知道你获取它的人地址的方法。 这就是为什么大多数邮件列表现在使用这个机制来确认 sign-ups 。 毕竟,任何人都可以放下 president@whitehouse.gov,甚至可以解析为合法的,但它不可能是另一端的人。

对于php,你不应该使用给定的模式与php验证一个 E-mail 地址,正确的方式我报价:

常见的用法和广泛的草率编码将为 E-mail 地址建立一个事实标准,这比记录的正式标准更严格。

这比所有其他non-RFC模式都好。 它甚至还不足以处理甚至 RFC 822,更不用说 RFC 5322. ,然而,它是

如果你想得到花哨和呆板的,实现一个完整的状态引擎 。 正则表达式只能作为基本的筛选器。 正规表达式 withproblem某人是南非,以便perfectly E-mail 地址相同,你( 假阳性) 无效,is not canhandle邮件表达马来西亚impolitefromthe金钥匙鲁莽和运用角度。 目的的状态引擎既可以验证,也可以更正 E-mail 地址,因为它根据每个RFC反汇编 E-mail 地址而被认为无效。 这可以让你有更愉快的体验,比如

指定的E-mail 地址'myemail@address,com'无效。 你是指'myemail@address.com'?

请参阅验证电子邮件地址,包括评论。 或者比较 E-mail 地址验证 正规表达式

Regular expression visualization

Debuggex演示

这取决于你的意思: 如果你正在讨论捕获每个有效的电子邮件地址,请使用以下命令:


(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t]
)+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:
rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(
?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ 
t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-
31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*
](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+
(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:
(?:rn)?[ t])*))*|(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z
|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)
?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:
rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[
 t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)
?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t]
)*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[
 t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*
)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t]
)+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)
*:(?:(?:rn)?[ t])*)?(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+
|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:r
n)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:
rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t
]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31
]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](
?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?
:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?
:rn)?[ t])*))*>(?:(?:rn)?[ t])*)|(?:[^()<>@,;:".[] 00-31]+(?:(?
:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?
[ t]))*"(?:(?:rn)?[ t])*)*:(?:(?:rn)?[ t])*(?:(?:(?:[^()<>@,;:".[] 
00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|
.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>
@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"
(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t]
)*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:
".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?
:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[
]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*|(?:[^()<>@,;:".[] 00-
31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|.|(
?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)?[ t])*(?:@(?:[^()<>@,;
:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([
^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:"
.[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[
]r]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[ t])*(?:[^()<>@,;:".
[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]
r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 
00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]
|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?(?:[^()<>@,;:".[] 
00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?:[^"r]|
.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[^()<>@,
;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]]))|"(?
:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*))*@(?:(?:rn)?[ t])*
(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".
[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t])*(?:[
^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[]
]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(?:rn)?[ t])*)(?:,s*(
?:(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:
".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(
?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[
["()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t
])*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t
])+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?
:.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|
Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*|(?:
[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".[
]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)*<(?:(?:rn)
?[ t])*(?:@(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["
()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)
?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>
@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*(?:,@(?:(?:rn)?[
 t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,
;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:.(?:(?:rn)?[ t]
)*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:
".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*)*:(?:(?:rn)?[ t])*)?
(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[["()<>@,;:".
[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])*)(?:.(?:(?:
rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z|(?=[[
"()<>@,;:".[]]))|"(?:[^"r]|.|(?:(?:rn)?[ t]))*"(?:(?:rn)?[ t])
*))*@(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])
+|Z|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*)(?:
.(?:(?:rn)?[ t])*(?:[^()<>@,;:".[] 00-31]+(?:(?:(?:rn)?[ t])+|Z
|(?=[["()<>@,;:".[]]))|[([^[]r]|.)*](?:(?:rn)?[ t])*))*>(?:(
?:rn)?[ t])*))*)?;s*)

( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html web ) 如果你正在寻找更简单的,但将捕获最有效的电子邮件地址,请尝试以下方法:


"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"

编辑:从链接:

这个正则表达式将只验证已经被删除并用空白( 这由模块完成) 替换的地址。

这取决于你想如何精确。 出于我的目的,我只是想避免像"@ aol.com" 或者""或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或"mary@aolcom这样的事情,我使用

 
/^S+@S+.S+$/

 

当然,它将匹配无效的电子邮件地址,但这是播放 90/10 规则的问题。

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


/(?(DEFINE)
 (?<address> (?&mailbox) | (?&group))
 (?<mailbox> (?&name_addr) | (?&addr_spec))
 (?<name_addr> (?&display_name)? (?&angle_addr))
 (?<angle_addr> (?&CFWS)? <(?&addr_spec)> (?&CFWS)?)
 (?<group> (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
 (?&CFWS)?)
 (?<display_name> (?&phrase))
 (?<mailbox_list> (?&mailbox) (?:, (?&mailbox))*)

 (?<addr_spec> (?&local_part) @ (?&domain))
 (?<local_part> (?&dot_atom) | (?&quoted_string))
 (?<domain> (?&dot_atom) | (?&domain_literal))
 (?<domain_literal> (?&CFWS)? [ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
 ] (?&CFWS)?)
 (?<dcontent> (?&dtext) | (?&quoted_pair))
 (?<dtext> (?&NO_WS_CTL) | [x21-x5ax5e-x7e])

 (?<atext> (?&ALPHA) | (?&DIGIT) | [!#$%&'*+-/=?^_`{|}~])
 (?<atom> (?&CFWS)? (?&atext)+ (?&CFWS)?)
 (?<dot_atom> (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
 (?<dot_atom_text> (?&atext)+ (?: . (?&atext)+)*)

 (?<text> [x01-x09x0bx0cx0e-x7f])
 (?<quoted_pair>  (?&text))

 (?<qtext> (?&NO_WS_CTL) | [x21x23-x5bx5d-x7e])
 (?<qcontent> (?&qtext) | (?&quoted_pair))
 (?<quoted_string> (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
 (?&FWS)? (?&DQUOTE) (?&CFWS)?)

 (?<word> (?&atom) | (?&quoted_string))
 (?<phrase> (?&word)+)

 # Folding white space
 (?<FWS> (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
 (?<ctext> (?&NO_WS_CTL) | [x21-x27x2a-x5bx5d-x7e])
 (?<ccontent> (?&ctext) | (?&quoted_pair) | (?&comment))
 (?<comment> ( (?: (?&FWS)? (?&ccontent))* (?&FWS)? ) )
 (?<CFWS> (?: (?&FWS)? (?&comment))*
 (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

 # No whitespace control
 (?<NO_WS_CTL> [x01-x08x0bx0cx0e-x1fx7f])

 (?<ALPHA> [A-Za-z])
 (?<DIGIT> [0-9])
 (?<CRLF> x0d x0a)
 (?<DQUOTE>")
 (?<WSP> [x20x09])
 )

 (?&address)/x

W3Chtml5规范 :


^[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])?)*$

上下文:

一个有效的E-mail 地址是一个字符串,它与ABNF的生产 [...] 匹配。

注意:这个需求是故意违反RFC 5322,它定义了一个语法 E-mail ( 在"@"字符) 地址同时太严格了,太模糊( 后"@"字符), 太松懈( 允许大多数用户不熟悉的注释,空白字符和引用字符串)的实际应用。

以下JavaScript-和Perl-compatible正则表达式是上述定义的实现。


/^[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])?)*$/

我想验证的电子邮件地址将被一个 ASP.NET web应用程序使用,它使用 System.Net.Mail 命名空间将电子邮件发送给一个人的列表。 所以,我不是使用一些非常复杂的正则表达式,而是尝试从地址创建一个MailAddress实例。 如果地址未正确形成,则 MailAddress construtor将引发异常。 这样,我知道我至少可以从门上得到电子邮件。 当然这是server-side验证,但至少你需要它。


protected void emailValidator_ServerValidate(object source, ServerValidateEventArgs args)
{
 try
 {
 var a = new MailAddress(txtEmail.Text);
 }
 catch (Exception ex)
 {
 args.IsValid = false;
 emailValidator.ErrorMessage ="email:" + ex.Message;
 }
}

...