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

我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。

你有或见过验证电子邮件的最佳正则表达式是什么?

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


当前回答

为这个问题发布的正则表达式现在已经过时了,因为新的通用顶级域(gTLD)即将到来(例如,伦敦、篮球、。通販). 要验证电子邮件地址,有两个答案(这将与绝大多数人相关)。

正如主要答案所说,不要使用正则表达式。只需通过向该地址发送电子邮件来验证它(捕获无效地址的异常)使用一个非常通用的正则表达式,至少确保他们使用的是一个类似于{something}@{some}的电子邮件结构。{一些}。使用一个详细的正则表达式是没有意义的,因为你不会全部抓住它们,几年后会有一个新的批处理,你必须再次更新正则表达式。

我决定使用正则表达式,因为不幸的是,有些用户没有读取表单,并将错误的数据放在错误的字段中。这至少会在他们试图将非电子邮件的内容输入到电子邮件输入字段时提醒他们,这样可以为您节省一些时间来支持用户处理电子邮件问题。

(.+)@(.+){2,}\.(.+){2,}

其他回答

为了使用JavaScript验证电子邮件地址,使用此功能更方便和高效(根据W3Schools):

function validateEmail()
{
    var x = document.f.email.value;
    var atpos = x.indexOf("@");
    var dotpos = x.lastIndexOf(".");
    if (atpos < 1 || dotpos < atpos+2 || dotpos+2 >= x.length)
    {
        alert("Not a valid e-mail address");
        return false;
    }
}

我用它,它很完美。

我将代码转换为Java以匹配编译器:

String pattern = "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-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-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";

问题标题相当通用,但是问题的主体表明它是关于基于PHP的解决方案的。将尝试解决这两个问题。

一般来说,对于所有编程语言:典型的验证“带有reg ex的电子邮件地址是任何基于互联网的服务提供商都应该避免的事情。域名和电子邮件地址种类的可能性已经大大增加,任何验证尝试都可能会导致拒绝某些有效用户进入您的系统。为了避免这种情况,最好的方法之一是向用户发送电子邮件确认它被接收。“普遍接受指导小组”的好朋友们编制了一份按语言排列的库列表,发现这些库符合/不符合与国际化域名和国际化电子邮件地址相关的各种参数。请在这里和这里找到这些文档的链接。

具体来说PHP:

PHP中有一个很好的库,即EmailValidator。它是一个电子邮件地址验证器,包括许多验证方法,如DNS验证。特别推荐的验证器称为RFCValidator,并根据多个RFC验证电子邮件地址。它在包容IDN和国际化电子邮件地址方面具有良好的合规性。

没有人提到本地化问题(i18n)。如果你的客户来自世界各地呢?

然后,您需要按国家/地区对正则表达式进行分类,我看到开发人员最终构建了一个大型字典或配置。检测用户的浏览器语言设置可能是一个很好的起点。

我不相信bortzmeyer所说的“语法(RFC 5322中指定的)太复杂了”(无法用正则表达式处理)。

这是语法(来自3.4.1。添加规范规范):

addr-spec       =   local-part "@" domain
local-part      =   dot-atom / quoted-string / obs-local-part
domain          =   dot-atom / domain-literal / obs-domain
domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext           =   %d33-90 /          ; Printable US-ASCII
                    %d94-126 /         ;  characters not including
                    obs-dtext          ;  "[", "]", or "\"

假设点原子、带引号的字符串、obs局部部分、obs域本身是正则语言,这是一个非常简单的语法。只需将addr-spec产品中的本地部分和域替换为它们各自的产品,您就拥有了一种可直接转换为正则表达式的正则语言。