如何在JavaScript中验证电子邮件地址?

5476

在将用户输入发送到服务器或尝试向其发送电子邮件之前,为了防止最基本的打字错误,我想在JavaScript中检查用户输入是否为电子邮件地址。 我该如何实现此目标?


23
@Alex 我添加这个评论的原因是,被接受的答案中建议的正则表达式会禁止现有的有效电子邮件地址,这对客户来说是一个很糟糕的开端。而真正大的问题是,即使地址被接受了,也不能确定它是否有效。可靠地验证提供的电子邮件地址是否有效的唯一方法是发送带有验证链接的邮件。因此,如果您的用例不要求验证电子邮件,请只进行最小限度的@测试;否则,请使用验证邮件。正则表达式只会提供糟糕的用户体验。 - David Mårtensson
7
@mikael1000,好的,但是当你根本不知道是否存在有效的电子邮件时,正则表达式验证有什么用处呢?如果您不想使用验证链接干扰客户,则只需进行最简单的验证<something> at <something>,然后就可以了。这将确保客户至少添加了可能是电子邮件的内容,除此之外的任何操作都是代码浪费,直到您实际进行验证为止。您还可以通过DNS查找来检查域名是否存在。 - David Mårtensson
2
非常相似:*如何使用正则表达式验证电子邮件地址?* - Peter Mortensen
我建议阅读这篇关于电子邮件语法如何工作的文章:https://debounce.io/blog/articles/email-syntax-error-explained/ - Iman
3
我必须承认,我不理解为什么要进行这么多验证,因为即使用户没有使用有效字符,也无法预测其是否进行了基本类型的输入。 只需在开头检查@和至少一个点即可。 - Watts Epherson
显示剩余5条评论
79个回答

4
您可以尝试以下方法:
var string = "hmharsh3@gmail.com"
var exp = /(\w(=?@)\w+\.{1}[a-zA-Z]{2,})/i
alert(exp.test(string))

4

使用正则表达式:

 /^[a-z][a-zA-Z0-9_.]*(\.[a-zA-Z][a-zA-Z0-9_.]*)?@[a-z][a-zA-Z-0-9]*\.[a-z]+(\.[a-z]+)?$/

例子:

function validateEmail(email) {
    var re = /^[a-z][a-zA-Z0-9_.]*(\.[a-zA-Z][a-zA-Z0-9_.]*)?@[a-z][a-zA-Z-0-9]*\.[a-z]+(\.[a-z]+)?$/;
    return re.test(email);
}

它应该只允许 @、. 和 _ 符号。


4
你可以使用以下正则表达式(来自于 w3resource(与W3C无关)):
/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(emailValue)

如果您使用Node,无论是前端还是后端都可以使用它。 我不了解其他后端语言,因此无法评估其他用例。

4
这个正则表达式在'user+addition@gmail.com'和'user@email.longdomain'上失败了。不要使用。 - Xizam
"user+addition" 是一个有效的电子邮件地址,而 "longdomain" 不一定是无效的。 - Mattia Rasulo
准确地说,没有正则表达式能够完全验证电子邮件的格式,即使它可以,也无法知道特定于域的规则,只需检查@并完成或发送验证电子邮件即可。其他任何操作都只会带来麻烦。 - David Mårtensson

4
如果您遇到以下错误:使用正则表达式具有安全风险。
那么这就是您需要的解决方案。此解决方案不受“正则表达式拒绝服务攻击(ReDoS)”的影响。
验证电子邮件地址的正则表达式(不受ReDoS影响):
/^[a-z0-9](?!.*?[^\na-z0-9]{2})[^\s@]+@[^\s@]+\.[^\s@]+[a-z0-9]$/

如果这个解决方案对您有用,请告诉我。 谢谢。


4

以下是正则表达式验证:

  • @符号之前不能有特殊字符
  • (-)和(.)不能在@之后放在一起,在@之后不能有特殊字符,@之前必须有2个字符 电子邮件长度应小于128个字符
function validateEmail(email) {
var chrbeforAt = email.substr(0, email.indexOf('@'));
if (!($.trim(email).length > 127)) {
    if (chrbeforAt.length >= 2) {
        var re = /^(([^<>()[\]{}'^?\\.,!|//#%*-+=&;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
        //var re = /[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 re.test(email);
    } else {
        return false;
    }
} else {
    return false;
}
}

3
如果您使用ng-pattern和Material,则可以完成此操作。
vm.validateEmail = '([a-zA-Z0-9_.]{1,})((@[a-zA-Z]{2,})[\\\.]([a-zA-Z]{2}|[a-zA-Z]{3}))';

3
使用 JavaScript 中的 URL 接口以最小实用的预期格式解析地址 user@host,然后检查它是否合理。接下来向其发送一条消息并查看是否有效(例如,要求收件人通过地址验证一次性令牌)。请注意,此操作处理 punycode、国际化,如下面的示例所示。
参考链接:https://developer.mozilla.org/en-US/docs/Web/API/URL 一个带简单测试的示例:
function validEmail(input=''){
    const emailPatternInput = /^[^@]{1,64}@[^@]{4,253}$/, emailPatternUrl = /^[^@]{1,64}@[a-z][a-z0-9\.-]{3,252}$/i;
    let email, url, valid = false, error, same = false;
    try{
        email = input.trim();
        // handles punycode, etc using browser's own maintained implementation
        url = new URL('http://'+email);
        let urlderived = `${url.username}@${url.hostname}`;
        same = urlderived === email;
        valid = emailPatternInput.test( email );
        if(!valid) throw new Error('invalid email pattern on input:' + email);
        valid = emailPatternUrl.test( urlderived );
        if(!valid) throw new Error('invalid email pattern on url:' + urlderived);
    }catch(err){
        error = err;
    };
    return {email, url, same, valid, error};
}

[
 'user+this@はじめよう.みんな'
, 'stuff@things.eu'
, 'stuff@things'
, 'user+that@host.com'
, 'Jean+François@anydomain.museum','هيا@יאללה'
, '试@例子.测试.مثال.آزمایشی'
, 'not@@really'
, 'no'
].forEach(email=>console.log(validEmail(email), email));

3
如果您正在使用Closure,则可以使用内置的goog.format.EmailAddress类型:

http://docs.closure-library.googlecode.com/git/class_goog_format_EmailAddress.html

例如:
goog.format.EmailAddress.isValidAddrSpec("blah@blah.com")

请注意,通过阅读上面链接的源代码,您可以看到评论中指出不支持国际化域名(IDN),它只旨在覆盖大多数地址。
// This is a fairly naive implementation, but it covers 99% of use cases.
// For more details, see http://en.wikipedia.org/wiki/Email_address#Syntax
// TODO(mariakhomenko): we should also be handling i18n domain names as per
// http://en.wikipedia.org/wiki/Internationalized_domain_name

3
<pre>
**The personal_info part contains the following ASCII characters.
1.Uppercase (A-Z) and lowercase (a-z) English letters.
2.Digits (0-9).
3.Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~
4.Character . ( period, dot or fullstop) provided that it is not the first or last character and it will not come one after the other.**
</pre>
*Example of valid email id*
<pre>
yoursite@ourearth.com
my.ownsite@ourearth.org
mysite@you.me.net
xxxx@gmail.com
xxxxxx@yahoo.com
</pre>
<pre>
xxxx.ourearth.com [@ is not present] 
xxxx@.com.my [ tld (Top Level domain) can not start with dot "." ]
@you.me.net [ No character before @ ]
xxxx123@gmail.b [ ".b" is not a valid tld ]
xxxx@.org.org [ tld can not start with dot "." ]
.xxxx@mysite.org [ an email should not be start with "." ]
xxxxx()*@gmail.com [ here the regular expression only allows character, digit, underscore and dash ]
xxxx..1234@yahoo.com [double dots are not allowed
</pre>
**javascript mail code**

    function ValidateEmail(inputText)
    {
    var mailformat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
    if(inputText.value.match(mailformat))
    {
    document.form1.text1.focus();
    return true;
    }
    else
    {
    alert("You have entered an invalid email address!");
    document.form1.text1.focus();
    return false;
    }
    }

我可能错误地解读了你的正则表达式,但似乎你只允许2-3个字符作为顶级域名?https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains - Janspeed
我可能对你的正则表达式理解有误,但似乎你只允许顶级域名为2-3个字符?https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains - undefined

3

最佳选择:D(符合RFC标准且没有“过于复杂”的错误):

function    isMail(mail)
{
    pattuser = /^([A-Z0-9_%+\-!#$&'*\/=?^`{|}~]+\.?)*[A-Z0-9_%+\-!#$&'*\/=?^`{|}~]+$/i;
    pattdomain = /^([A-Z0-9-]+\.?)*[A-Z0-9-]+(\.[A-Z]{2,9})+$/i;

    tab = mail.split("@");
    if (tab.length != 2)
        return false;
    return (pattuser.test(tab[0]) && pattdomain.test(tab[1]));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接