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


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


3259


起源


虽然这个解决方案可能很简单,但我确信这是人们将谷歌搜索的有用的东西之一,并且值得在网站上自己输入 如果只有谷歌会成为第一个看的地方:)只要看看每隔一段时间关闭的重复项。 - Esteban Küber
我相信这是人们将谷歌搜索的有用的东西之一  大声笑,事实上,我是如何遇到这个问题的! - Peter C
可能重复 验证电子邮件地址的最佳正则表达式是什么? - Brad Mace
请说得对,太多网站不喜欢我的电子邮件地址“firstName@secondName.name”,并非所有顶级域名都以2或3个字母结尾。 - Ian Ringrose
任何支持使用正则表达式检查电子邮件我100%反对。我厌倦了被告知我的电子邮件地址“foo+bar@gmail.com”无效。最好的选择是要求用户输入两次电子邮件,如果你必须使用正则表达式检查器,那么告诉用户他们的电子邮件地址似乎没有效果,并询问他们是否确定他们输入了对。甚至还指出了什么没有在正则表达式检查中检查,但不要阻止他们提交表格。 - Soundfx4


答案:


运用 常用表达 可能是最好的方式。你可以看到一堆测试 这里 (取自

function validateEmail(email) {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(String(email).toLowerCase());
}

以下是接受unicode的常规表达示例:

var re = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;

但请记住,不应该只依赖JavaScript验证。可以轻松禁用JavaScript。这也应该在服务器端验证。

以下是上述操作的示例:

function validateEmail(email) {
  var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return re.test(email);
}

function validate() {
  var $result = $("#result");
  var email = $("#email").val();
  $result.text("");

  if (validateEmail(email)) {
    $result.text(email + " is valid :)");
    $result.css("color", "green");
  } else {
    $result.text(email + " is not valid :(");
    $result.css("color", "red");
  }
  return false;
}

$("#validate").bind("click", validate);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form>
  <p>Enter an email address:</p>
  <input id='email'>
  <button type='submit' id='validate'>Validate!</button>
</form>

<h2 id='result'></h2>


3795



此正则表达式消除了有效的使用中的电子邮件。不使用。谷歌为“RFC822”或“RFC2822”获得正确的正则表达式。 - Randal Schwartz
@Randall:你能举例说明一个不会通过的电子邮件地址吗? - rossipedia
@GoodPerson我刚试过给n @ ai发邮件告诉他/她他们有一个很酷的电子邮件地址。但是,唉,gmail不会让我。我怀疑通过电子邮件与他人沟通的问题不仅仅是我网站的javascript验证!但感谢您接受挑战。 - Ben Roberts
对于所有人评论这是“足够好”:看,你只是在想这个问题是错的。没关系。这是您可以为用户做出的选择。我并不生气。但是,你知道,从技术上讲,你是示范性的,可证明是错误的。 - Wayne Burkett
您无法验证电子邮件地址,期限。唯一可以验证电子邮件地址的人是电子邮件地址的提供者。例如,这个答案说这些电子邮件地址: %2@gmail.com, "%2"@gmail.com, "a..b"@gmail.com, "a_b"@gmail.com, _@gmail.com, 1@gmail.com , 1_example@something.gmail.com 这些都是有效的,但Gmail绝不会允许任何这些电子邮件地址。您应该接受电子邮件地址并向该电子邮件地址发送电子邮件,并使用用户必须访问的代码/链接以确认其有效性。 - Kevin Fegan


为了完整, 在这里你有另一个符合RFC 2822的正则表达式

官方标准被称为 RFC 2822。它描述了有效电子邮件地址必须遵守的语法。您可以 (但你不应该  - 请继续阅读用这个正则表达式实现它:

(?:[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])+)\])

(...)如果我们使用双引号和方括号省略语法,我们会得到更实际的RFC 2822实现。 它仍将匹配当前实际使用的99.99%的电子邮件地址。

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

您可以进行的进一步更改是允许任何双字母国家/地区代码顶级域,并且只允许特定的通用顶级域。 这个正则表达式过滤虚拟电子邮件地址,如 asdf@adsf.adsf。您 在添加新的顶级域名时需要更新它

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b

因此,即使遵循官方标准,仍然需要进行权衡。 不要盲目地从在线图书馆或论坛中复制正则表达式。始终使用您自己的数据和您自己的应用程序测试它们。

强调我的


612



注意:“在实际使用中 今天“编写代码时可能已经有效,返回200x。代码 将 可能会在特定年份之后继续使用。 (如果我为每一个“meh都有一分钱,没有人会使用4 +通讯顶级域名,除了那些特定的那些”我必须解决,我可以在全球的铜和镍市场上角落;)) - Piskvor
对于RFC 2822的实际实现,应稍微修改结尾以防止单个字符串域扩展。 / [A-Z0-9!#$%&'* + \ / =?^ _{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_{|}〜 - ] +)* @?(?:?[A-Z0-9](在[a-Z0-9 - ] * [A-Z0-9])\)+ [A-z0- 9] [A-Z0-9 - ] * [A-Z0-9] / - will Farrell
此外,第一部分应该是(?:[A-z,大写字母A,以避免在用户资本化其电子邮件地址时出现漏报)。 - Don Rolling
随着规范, d._.___d@gmail.com 不是有效的电子邮件,但仍然检测到它是正确的 - Raptor
@DonRolling不要这样做。这不仅意味着“A到Z,a到z”,它还意味着“[\] ^ _`”,因为它们是 在之间 “Z”和“a”。使用 \w或者更好,只是在对它做任何事情之前将电子邮件地址小写,因为这是惯例。 - kirb


我稍微修改了Jaymon对那些想要以下列形式进行简单验证的人的答案:

anystring@anystring.anystring

正则表达式:

/\S+@\S+\.\S+/

JavaScript函数示例:

function validateEmail(email) 
{
    var re = /\S+@\S+\.\S+/;
    return re.test(email);
}

551



/\S+@\S+\.\S+/.test('name@again@example.com')  true - neoascetic
@neoascetic Shazam! /[^\s@]+@[^\s@]+\.[^\s@]+/.test('name@again@example.com') // false - n0nag0n
您可以实现20倍的长度,这可能会导致少数用户出现问题,并且可能在将来无效,或者您可以获取ImmortalFirefly的版本以确保他们至少付出努力使其看起来真实。根据您的应用程序,可能更容易遇到某人会生气,因为您不接受他们的非传统电子邮件,而不是通过输入不存在的电子邮件地址导致问题的人(他们无论如何都可以通过输入100%有效的RFC2822电子邮件地址,但使用未注册的用户名或域名)。 Upvoted! - user83358
@ImmortalFirefly,你提供的正则表达式实际上会匹配 name@again@example.com。尝试将您的行粘贴到JavaScript控制台中。我相信你的意图是只匹配整个文本,这需要文本'^'的开头和文本'$'运算符的结尾。我正在使用的是 /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test('name@again@example.com') - OregonTrail
请问人们不要抱怨误报吗?这是一个简单的正则表达式,可以捕获95%的错误。如果你想使用真正巨大的正则表达式 而且还远非完美,看到其他答案。 - André Chalella


你决定使用正则表达式验证电子邮件,你需要了解的第二件事: 这可能不是一个好主意。一旦你接受了这个,那里有很多实现可以让你到达那里, 这篇文章很好地总结了它们。

简而言之,唯一的方法是绝对,确定用户输入的内容实际上是电子邮件,实际上是发送电子邮件并查看会发生什么。除此之外,这一切都只是猜测。


293



-1为什么我要花时间验证一个甚至没有通过正则表达式控件的电子邮件地址? - kommradHomer
@PaoloBergantino我只是没有,除了正则表达式是一个坏主意,只是一个猜测。正则表达式无效地址是%100无效地址。 - kommradHomer
@kommradHomer - “正则表达式无效”地址几乎总是有效的,因为用于验证电子邮件地址的正则表达式几乎肯定是错误的并且将排除有效的电子邮件地址。电子邮件地址是 name_part@domain_part 几乎任何东西, 包含 一个 @,在name_part中有效;地址 foo@bar@machine.subdomain.example.museum 是合法的,虽然必须逃脱 foo\@bar@machine....。一旦电子邮件到达域,例如'example.com'该域可以“本地”路由邮件,因此可以存在“奇怪的”用户名和主机名。 - Stephen P
旅行者回答的第二个正则表达式 stackoverflow.com/a/1373724/69697 是实用的,应该几乎没有假阴性。我同意@kommradHomer - 为什么如果你不需要发送电子邮件?我可以理解对不可理解的正则表达式的反思性厌恶以及保持代码简单的愿望,但这是几行代码,可以通过立即清除绝对无效的项目来节省您的服务器很多麻烦。正则表达式本身是无益的,但它是服务器端验证的良好补充。 - Ben Regenspan
@dmur我承认“几乎总是有效的”可能是夸大它,但我的网站经常拒绝我的(完全有效且有效的)电子邮件地址,因为我有一个 .us 域或因为我使用了 + 在左边 @  - 许多地方已经修复了这些令人震惊的错误,但是本地部分(@的左边)可以 什么 域名所有者想要的。 - >“foo@bar.com”@ example.com < - 是有效的电子邮件地址。 - Stephen P


哇,这里有很多复杂性。如果您只想捕获最明显的语法错误,我会做这样的事情:

\S+@\S+

它通常捕获用户做出的最明显的错误,并确保表单大部分是正确的,这就是JavaScript验证的全部内容。


282



+1发送电子邮件并查看发生的情况是确认电子邮件地址的唯一真正可靠的方法,除了简单的正则表达式匹配之外,不需要做更多的事情。 - kommradHomer
你仍然可以保持简单但做多一点以确保它有“。”在@之后的某个地方只跟数字或数字一起,所以像我这里,我@在这里@和我@ herecom这样的东西无效... ^ \ S + @ \ S + [\。] [0-9a-z ] + $ - Tim Franklin
我认为电子邮件地址可以包含空格。它可能更好用 .+@.+ - Sam
/\S+@\S+/.test("áéíóúý@ÁÉÍÓÚÝð")  true - gtournie
@gtournie没人关心。没有人会将其输入电子邮件字段 意外地,这就是所有前端验证适用于:防止人们在电子邮件字段中意外输入错误的信息,例如他们的名字。 - meagar♦


HTML5本身有电子邮件验证。如果您的浏览器支持HTML5,那么您可以使用以下代码。

<form><input type="email" placeholder="me@example.com">
    <input type="submit">
</form>

的jsfiddle 链接

来自 HTML5规范

一个 合法的邮件地址 是一个匹配的字符串 email生成以下ABNF,其字符集为Unicode。

email   = 1*( atext / "." ) "@" label *( "." label )
label   = let-dig [ [ ldh-str ] let-dig ]  ; limited to a length of 63 characters by RFC 1034 section 3.5
atext   = < as defined in RFC 5322 section 3.2.3 >
let-dig = < as defined in RFC 1034 section 3.5 >
ldh-str = < as defined in RFC 1034 section 3.5 >

这个要求是一个 故意违反 RFC 5322,它定义了同时过于严格(在“@”字符之前)的电子邮件地址的语法,过于含糊(在“@”字符之后),并且过于宽松(允许注释,空白字符和引用)在大多数用户不熟悉的方式中的字符串)在这里具有实际用途。

以下JavaScript和Perl兼容的正则表达式是上述定义的实现。

/^[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])?)*$/

165



这很好,但问题在于它必须在一个内部 form 标签并由提交 submit 投入,并非每个人都有这样的奢侈品。此外,您无法真正设置错误消息的样式。 - Jason
我在下面添加了一个答案,将您从表单中解放出来并提交。但是,浏览器通常也只应用一些合理性检查而不是完整的RFC 822验证。 - Boldewyn
@ br1:它不是因为没有“a”顶级域存在而无效。你的内联网有什么决定一些IP吗? - flying sheep
Html5电子邮件字段类型接受用户@ email等电子邮件 - Puce
这在Safari中不起作用 - Mr Wilde


我发现这是最好的解决方案:

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

它允许以下格式:

1. prettyandsimple@example.com
2. very.common@example.com
3. disposable.style.email.with+symbol@example.com
4. other.email-with-dash@example.com
9. #!$%&'*+-/=?^_` {} |〜@ example.org
6.“()[] :,; @ \\\”!#$%&'* +  -  / =?^ _`{} | 〜。一“@ example.org
7.“”@ example.org(引号之间的空格)
8.üñîçøðé​​@example.com(本地部分的Unicode字符)
9.üñîçøðé​​@üñîçøðé​​.com(域部分中的Unicode字符)
10.Pelé@example.com(拉丁文)
11.δοκιμή@παράδειγμα.δοκιμή(希腊语)
12.我买@屋企。香港(中文)
13.甲斐@黒川。日本(日文)
14.чебурашка@ящик-с-апельсинами.рф(西里尔文)

它显然是多功能的,允许所有重要的国际角色,同时仍然执行基本的any@anything.anything格式。它将阻止RFC在技术上允许的空间,但它们非常罕见,我很乐意这样做。


95



这正是我在做的事情。所有这些“复杂”的答案都会产生问题:它们要么不允许使用微弱的代码IDN,要么使用一组固定的TLD,或者不必要地限制用户在他们的电子邮件前缀中使用[@çμ.ö等字符(在@之前)或域名。前端的JavaScript(不用于后端使用原因)不足以验证安全性原因。那么为什么不帮助用户防止基本的拼写错误。基本拼写错误是:忘记TLD或用户前缀(在@之前)或域部分或错误类型 @ 如 . (或相反亦然)。因为我们必须在服务器端更加严格。 - Hafenkranich
出于某些奇怪的原因 username@domain.com 不适用于此模式 - einstein
@einstein它确实符合你的例子: regex101.com/r/vX2eJ0/1 - Andrew
根据你的正则表达“_.............. kamal@gmail.com”是有效的,这不应该! - Kamal Nayan
如果你想修补这个解决方案,这里是陈述的RegEx示例: regex101.com/r/AzzGQU/2 - ryanm


在现代浏览器中,您可以使用纯粹的JavaScript和@Sushil的答案构建 DOM

function validateEmail(value) {
  var input = document.createElement('input');

  input.type = 'email';
  input.required = true;
  input.value = value;

  return typeof input.checkValidity === 'function' ? input.checkValidity() : /\S+@\S+\.\S+/.test(value);
}

我在小提琴中放了一个例子 http://jsfiddle.net/boldewyn/2b6d5/。结合功能检测和来自的简单验证 Squirtle的回答,它让你从正则表达式大屠杀中解放出来,并且不会在旧浏览器上出现问题。


76



这是解决问题的一个聪明的想法,但它不起作用,因为浏览器也有蹩脚的验证。例如。 .@a 验证为 true 在当前版本的Chrome,Firefox和Safari中。 - Hank
@HenryJackson不幸的是,在这种情况下是的。这是因为根据RFC,它是一个有效的电子邮件地址(想想内部网)。如果浏览器验证过于狭窄并产生漏报,浏览器就会被烧烤。 - Boldewyn
更新以包含功能检测和优雅降级,现在它不会在新浏览器中中断,但使用您喜欢的任何正则表达式。 - Ronny
好的解决方案遗憾的是,这仅适用于HTML5 +。 - Edward Olamisan
这是迄今为止最原始问题的最佳解决方案。是的,它使用的是HTML5,但是大多数需要这种精确度的应用程序肯定已经以某种其他方式依赖HTML5了,所以没有实际意义。我们不可能确定某人的电子邮件是否有效,而无需让他们验证它,所以我们真的不应该投入这么多时间或精力来验证它。快速检查任何明显的语法或尝试顽皮是我们应该花费的全部努力。 - Woody Payne