在Javascript中验证电子邮件地址,并与非ASCII字符兼容

时间:2012-10-21 17:41:36

标签: javascript regex internationalization email-validation non-ascii-characters

有许多正则表达式可用于验证电子邮件地址,但大多数正则表达式与非ASCII字符不兼容。一旦电子邮件地址包含非ASCII字符,例如'Rδοκιμή@παράδειγμα.δοκιμή'或'管理员@中国互联网络信息中心。中国',他们就无法正确识别它。如何构造一个用于验证电子邮件地址并与非ASCII字符兼容的正则表达式?

3 个答案:

答案 0 :(得分:4)

根据this source,JavaScript不通过其RegExp类提供任何Unicode支持,它支持\ uFFFF匹配单个Unicode代码点作为其字符串语法的一部分。
因此,为了定义Unicode字符的匹配项,应该创建一组\ uXXXX符号。列出的插件here可以创建Unicode正则表达式,并且可以在使用XRegExp JavaScript库时用于定义Unicode正则表达式。

这是函数,它测试有效的ASCII电子邮件地址:

/**
 * Checks if string contains valid email address as described
 * in RFC 2822: http://tools.ietf.org/html/rfc2822#section-3.4.1
 * This function omits the syntax using double quotes and square brackets
 * @return {Boolean}    True, if test succeeded.
 */
String.prototype.checkEmail = function()
{
    var reEmail = /^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
    return reEmail.test(this);
}

// Usage example
alert( "some_valid_email@somewhere.com".checkEmail() ); // true
alert( "invalid_email.com".checkEmail() ); // false

为了使其适用于Unicode字符串,可以包含XRegExp库并使用\\p{L}而不是a-z。这是完整的代码:

<!DOCTYPE html>
<html>
<head>
    <script src="xregexp-all-min.js"></script>
    <script>
        /**
         * Checks if string contains valid email address as described
         * in RFC 2822: http://tools.ietf.org/html/rfc2822#section-3.4.1
         * This function omits the syntax using double quotes and square brackets
         * @return {Boolean}    True, if test succeeded.
         */
        String.prototype.checkEmailX = function()
        {
            var reEmail = XRegExp("^[\\p{L}0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[\\p{L}0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-9])?$");
            return reEmail.test(this);
        }

        alert( "true = " + "Rδοκιμή@παράδειγμα.δοκιμή".checkEmailX() ); // true
        alert( "true = " +"管理员@中国互联网络信息中心.中国".checkEmailX() ); // true
        alert( "true = " +"test@test.am".checkEmailX() ); // true
        alert( "false = " +"test_test.am".checkEmailX() ); // false
        alert( "true = " +"test@ράδ.am".checkEmailX() ); // true
    </script>
</head>
<body>
</body>
</html>

答案 1 :(得分:4)

我不得不写一些关于如何使用正则表达式验证电子邮件地址的文章。不幸的是,结果是无法以这种方式验证电子邮件地址

当然你想知道原因。

  1. 看看examples of valid email addresses in the Wikipedia article。编写能够满足所有这些标准的正则表达式几乎是不可能的。
  2. 您肯定已经了解了本地顶级域名。这就是你提问的原因。但是,您可能没有意识到除了“标准”国家TLD之外,我们可能只有任何名称。它是一个移动的目标,所以......
  3. 并无所有域名注册管理机构遵循的具体政策。我发现例如日语注册表允许ideographic full stops(全宽和半宽)作为标签分隔符。我不知道它是如何工作的,但这就是他们允许的。此外,事实证明日本和中国注册管理机构的最大标签长度存在差异。我看不出如何用正则表达式验证它。
  4. 那么我们如何验证电子邮件呢?一个想法是简单地询问是否存在给定域的MTA(这在前端无法完成,即使用客户端JavaScript)。不幸的是,它会带来DOS攻击的风险,因此没有必要提出最好的想法。当然,您不知道地址在给定服务器上是否有效。为此,您需要连接到服务器并发出VRFY命令,但多亏了垃圾邮件发送者,大多数服务器都会回复“550 No such user”。

    如果验证的目的仅仅是为了避免用户的错误,您可能需要添加其他字段并让用户重新键入电子邮件(这也不是最好的主意)。

答案 2 :(得分:3)

请不要过度复杂化。

花一点时间思考你为什么需要它。很可能是因为你想给你的用户发一封电子邮件,对吗?所以我主张最简单的电子邮件验证正则表达式:

/@/

完成。它将验证所有有效的电子邮件地址。它也会错误地验证很多看起来像一个但实际上并不有效的东西,但是大多数错误要么不填写表单字段,要么混淆字段并在其他字段中输入错误的内容。

另外,您会注意到,如果您的邮件反弹,电子邮件地址无效。地址的存在是正则表达式无法为你做的事情。