多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。
我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。
你有或见过验证电子邮件的最佳正则表达式是什么?
我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。
多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。
我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。
你有或见过验证电子邮件的最佳正则表达式是什么?
我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。
当前回答
虽然已经添加了非常详细的答案,但我认为对于一个正在寻找验证电子邮件地址或从Java字符串中获取所有电子邮件地址的简单方法的开发人员来说,这些答案已经足够复杂了。
public static boolean isEmailValid(@NonNull String email) {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
就正则表达式而言,我总是使用这个正则表达式,这适用于我的问题。
"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}"
如果您希望通过匹配电子邮件正则表达式从字符串中查找所有电子邮件地址。您可以在此链接中找到方法。
其他回答
完全符合RFC 822的正则表达式由于其长度而效率低下且晦涩难懂。幸运的是,RFC 822被两次取代,当前的电子邮件地址规范是RFC 5322。RFC 5322产生了一个正则表达式,如果研究几分钟就可以理解,并且对于实际使用来说足够有效。
一个符合RFC 5322的正则表达式可以在页面顶部找到:http://emailregex.com/但使用的IP地址模式在互联网上浮动,错误是允许点分隔地址中的任何无符号字节十进制值为00,这是非法的。它的其余部分似乎与RFC 5322语法一致,并通过了几个使用grep-Po的测试,包括域名、IP地址、坏域名以及带引号和不带引号的帐户名。
纠正了IP模式中的00错误,我们获得了一个有效且相当快的正则表达式。(抓取呈现的版本,而不是markdown,以获取实际代码。)
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^ _`{|}~-]+)*|“(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-#x09\x0b#x0c\x10e-\x7f])*”)@(?:(?:[?:[a-z0-9](?:a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-#x09\x0b#x0c\x10e-\x7f】)+)\])
or:
(?:[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])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-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])+)\])
下面是上述正则表达式的有限状态机图,它比正则表达式本身更清楚
Perl和PCRE中更复杂的模式(例如PHP中使用的正则表达式库)可以正确地解析RFC 5322而不会出现问题。Python和C#也可以做到这一点,但它们使用的语法与前两种不同。然而,如果您被迫使用许多功能较弱的模式匹配语言之一,那么最好使用真正的解析器。
同样重要的是要理解,根据RFC验证它绝对不会告诉您该地址是否确实存在于所提供的域中,或者输入该地址的人是否是其真正的所有者。人们总是以这种方式向其他人注册邮件列表。修复这一问题需要一种更高级的验证,包括向该地址发送一条消息,该消息包含一个确认令牌,该令牌与该地址在同一网页上输入。
确认令牌是知道您获得输入者地址的唯一方法。这就是为什么现在大多数邮件列表都使用该机制来确认注册。毕竟,任何人都可以放下president@whitehouse.gov,这甚至会被解析为合法,但不太可能是另一端的人。
对于PHP,您不应该使用“用PHP验证电子邮件地址”中给出的模式,我引用的正确方法是:
常见的用法和广泛的草率编码可能会为电子邮件地址建立一个事实上的标准,这比记录的正式标准更具限制性。
这并不比其他所有非RFC模式更好。它甚至不足以处理RFC 822,更不用说RFC 5322了。然而,这一个是。
如果你想变得花哨和迂腐,就实现一个完整的状态引擎。正则表达式只能充当基本过滤器。正则表达式的问题是,从用户的角度来看,告诉某人他们完全有效的电子邮件地址是无效的(假阳性),因为你的正则表达式无法处理它,这是粗鲁和不礼貌的。用于此目的的状态引擎可以验证甚至纠正电子邮件地址,否则这些地址将被视为无效,因为它根据每个RFC分解电子邮件地址。这可能会带来更愉悦的体验,比如
指定的电子邮件地址'myemail@address,com'无效。你是说myemail@address.com'?
另请参阅验证电子邮件地址,包括注释。或比较电子邮件地址验证正则表达式。
Debugex演示
HTML5规范建议使用一个简单的正则表达式来验证电子邮件地址:
/^[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])?)*$/
这故意不符合RFC 5322。
注意:这一要求是故意违反RFC 5322的,RFC 5322为电子邮件地址定义了一种语法,该语法同时太严格(在@字符之前)、太模糊(在@符号之后)和太松散(允许注释、空白字符和引用字符串以大多数用户不熟悉的方式),在这里无法实际使用。
根据RFC 3696勘误表1690,总长度也可以限制为254个字符。
也许是最好的:
/^[a-zA-Z0-9]+([-._][a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-.][a-zA-Z0-9]+)*\.[a-zA-Z]{2,7}$/
以字母或数字开头。它可能包括“-__”,以“.”结尾,并且少于七个字符(例如.company)。
Cal Henderson(Flickr)写了一篇名为《用PHP解析电子邮件地址》的文章,并展示了如何正确解析符合RFC(2)822的电子邮件地址。
您还可以获得PHP、Python和Ruby的源代码,这是CreativeCommons许可的。
我知道这个问题是关于正则表达式的,但我猜,在阅读这些解决方案的所有开发人员中,90%都在尝试验证浏览器中显示的HTML格式的电子邮件地址。
如果是这种情况,我建议查看新的HTML5<inputtype=“email”>表单元素:
HTML5:
<input type="email" required />
CSS 3:
input:required {
background-color: rgba(255, 0, 0, 0.2);
}
input:focus:invalid {
box-shadow: 0 0 1em red;
border-color: red;
}
input:focus:valid {
box-shadow: 0 0 1em green;
border-color: green;
}
它是在HTML5表单验证没有JS-JSFidle代码游乐场。
这有两个优点:
自动验证,无需定制解决方案:简单易实现没有JavaScript,如果禁用了JavaScript也不会出现问题没有服务器需要为此计算任何东西用户有即时反馈旧浏览器应自动回退到输入类型“文本”移动浏览器可以显示专用键盘(@-键盘)使用CSS 3,表单验证反馈非常简单
明显的缺点可能是缺少对旧浏览器的验证,但这会随着时间的推移而改变。比起这些疯狂的正则表达式杰作,我更喜欢这个。
另请参见:
没有JS的HTML5表单验证-JSFiddle-代码游乐场Web表单-深入HTML5。疯狂的一种形式SUMO上的HTML5表单验证