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

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

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

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


当前回答

出于我的目的,我需要一种方法来提取显示名称(如果提供)。感谢上提供的其他答案和正则表达式https://emailregex.com/我提出了以下解决方案:

/^(?:([^<]*?)\s*<)?((?:[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])+)\]))>?$/gi

这与显示名称(=组1)+电子邮件地址(=组2)相匹配。

匹配示例:

john.doe@example.com
john.o'doe@example.com
John <john@doe.com>
<john@doe.com>
This is <john@127.0.0.1>

使用测试https://regex101.com/

当然,正如其他答案中提到的,还需要对显示名称和电子邮件地址的长度进行额外验证(不应超过320个UTF-8字节)。

其他回答

为了使用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;
    }
}

我用它,它很完美。

出于我的目的,我需要一种方法来提取显示名称(如果提供)。感谢上提供的其他答案和正则表达式https://emailregex.com/我提出了以下解决方案:

/^(?:([^<]*?)\s*<)?((?:[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])+)\]))>?$/gi

这与显示名称(=组1)+电子邮件地址(=组2)相匹配。

匹配示例:

john.doe@example.com
john.o'doe@example.com
John <john@doe.com>
<john@doe.com>
This is <john@127.0.0.1>

使用测试https://regex101.com/

当然,正如其他答案中提到的,还需要对显示名称和电子邮件地址的长度进行额外验证(不应超过320个UTF-8字节)。

几乎添加了一个新域“yandex”。可能的电子邮件:test@job.yandex.而且还支持大写字母,因此acrosman解决方案的一个小修改版本是:

^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,6})$

几乎我见过的每一个正则表达式(包括一些Microsoft使用的正则表达式)都不允许通过以下有效电子邮件:simon-@hotmail.com

我刚刚有一个真正的客户,他的电子邮件地址是这种格式的,他无法下订单。

以下是我的决定:

不会有假阴性的最小正则表达式。或者,使用MailAddress构造函数进行一些附加检查(见下文):检查常见的拼写错误.cmo或.gimal.com,并要求确认“您确定这是正确的电子邮件地址吗?看起来可能有错误。”如果用户确定,请允许他们接受键入的内容。在实际发送电子邮件时处理反弹,并手动验证它们以检查是否存在明显错误。


try
{
    var email = new MailAddress(str);

    if (email.Host.EndsWith(".cmo"))
    {
        return EmailValidation.PossibleTypo;
    }

    if (!email.Host.EndsWith(".") && email.Host.Contains("."))
    {
        return EmailValidation.OK;
    }
}
catch
{
    return EmailValidation.Invalid;
}

对于Angular2/Angular7,我使用以下模式:

emailPattern=“^[a-zA-Z0-9-_.+-]+@[a-zA-APP-GW-9-]+[.]+[a-zA-62-9-.]+(\\s)*”;私有createForm(){this.form=this.formBuilder.group({email:['',[Validators.required,Validators.pattern(this.emailPattern)]]});}

它还允许在结尾处添加额外的空间,在将其发送到后端之前,应该将其截断,但某些用户,特别是移动用户,很容易在结尾处错误地添加空间。