电子邮件地址中允许使用哪些字符?

What characters are allowed in an email address?

提问人:WildWezyr 提问时间:1/12/2010 最后编辑:kevinarpeWildWezyr 更新时间:7/7/2022 访问量:1244646

问:

我不是在问完整的电子邮件验证。

我只想知道电子邮件地址中允许的字符和部分字符。这可能过于简单化了,也许电子邮件地址可以采取其他形式,但我不在乎。我只问这个简单的形式:(例如wild.w[email protected])和两个部分中允许的字符。user-nameserveruser-name@server

表单 电子邮件 验证 电子邮件地址

评论

263赞 Dan Herbert 1/12/2010
这是允许的。当网站不允许它时,它会让我发疯,因为我的电子邮件中有一个,而且很多网站都不允许它。++
12赞 John Y 7/21/2012
前面的问题涉及相同的材料:stackoverflow.com/questions/760150/。可悲的是,尽管这个问题比这个问题大了将近 8 个月,但旧问题有更好的答案。下面的几乎所有答案在最初发布时都已经过时了。请参阅维基百科条目(别担心,它有相关的官方参考资料)。
29赞 user253751 7/8/2014
与几个答案相反,如果引用,电子邮件地址的本地部分允许使用空格。 是有效的。"hello world"@example.com
11赞 Kevin Fegan 9/27/2016
@LaraRuffleColes - 对于 Gmail,当您创建电子邮件帐户时,它不允许您创建包含“+”号的地址。“+”号(“加号地址”)允许任何拥有 Gmail 地址的人在其用户名末尾添加一个“+”号,然后添加一个“字符串”,以创建一个“备用”(“别名”)电子邮件地址以用于其帐户。示例:“[email protected]”、“[email protected]”。一个典型的(可能是“主要”)用途是能够为您的帐户创建别名电子邮件地址,允许您标记和过滤传入的电子邮件,理论上按发件人过滤。
10赞 Dan Herbert 4/7/2018
@Andrew 反之则更为常见。如果一个网站不能被信任允许正确的电子邮件地址,我不相信他们会处理我的个人信息。

答:

990赞 Anton Gogolev 1/12/2010 #1

请参阅 RFC 5322:Internet 邮件格式,并在较小程度上参见 RFC 5321:简单邮件传输协议

RFC 822 也涵盖了电子邮件地址,但它主要涉及其结构:

 addr-spec   =  local-part "@" domain        ; global address     
 local-part  =  word *("." word)             ; uninterpreted
                                             ; case-preserved
 
 domain      =  sub-domain *("." sub-domain)     
 sub-domain  =  domain-ref / domain-literal     
 domain-ref  =  atom                         ; symbolic reference

像往常一样,维基百科有一篇关于电子邮件地址的体面文章

电子邮件地址的本地部分可以使用以下任何 ASCII 字符:

  • 大写和小写拉丁字母 to 和 toAZaz;
  • digits 设置为09;
  • 特殊字符!#$%&'*+-/=?^_`{|}~;
  • dot ,前提是除非引用,否则它不是第一个或最后一个字符,并且除非引用,否则它不会连续出现(例如 是不允许的,但被允许);.[email protected]"John..Doe"@example.com
  • 空格和字符是有限制的(它们只允许在带引号的字符串内,如下文所述,此外,反斜杠或双引号前面必须有一个反斜杠);"(),:;<>@[\]
  • 允许在本地部分的两端使用括号进行注释;例如: 并且都等价于 。john.smith(comment)@example.com(comment)[email protected][email protected]

除了 ASCII 字符之外,自 2012 年起,您还可以使用上面的国际字符,编码为 UTF-8,如 RFC 6532 规范中所述并在维基百科上进行解释。请注意,截至 2019 年,这些标准仍标记为“已提议”,但正在缓慢推出。此规范中的更改实质上将国际字符添加为有效的字母数字字符(atext),而不影响允许和限制的特殊字符(如 和 )的规则。U+007F!#@:

有关验证,请参阅使用正则表达式验证电子邮件地址

该部件定义如下domain

协议的 Internet 标准(征求意见)规定组件主机名标签只能包含 ASCII 字母 through(以不区分大小写的方式)、数字 through 和 连字符 ()。RFC 952 中的原始主机名规范规定,标签不能以数字或连字符开头,也不得以连字符结尾。但是,随后的规范 (RFC 1123) 允许主机名标签以数字开头。不允许使用其他符号、标点符号或空格。az09-

评论

24赞 Dan Herbert 1/12/2010
@WildWzyr,没那么简单。电子邮件地址对允许的内容有很多规则。参考规范比列出所有规范更简单。如果您想要完整的正则表达式,请查看此处以了解为什么它不那么简单: regular-expressions.info/email.html
6赞 1/12/2010
没有简单的清单,仅仅因为你想要一些简单的东西并不意味着它会如此。有些字符只能位于某些位置,而不能位于其他位置。你不可能一直拥有你想要的东西。
16赞 Mark Pim 1/12/2010
@WildWezyr 好吧,在本地部分允许使用句号字符。但不是在开始或结束时。或者用另一个句号。因此,答案并不像只是一个允许的字符列表那么简单,关于如何使用这些字符是有规则的 - 不是有效的电子邮件地址,但即使两者都使用相同的字符。[email protected][email protected]
14赞 Chinmay Kanchi 1/12/2010
另外,请记住,随着国际化域名的加入,允许的字符列表将爆炸式增长。
53赞 ZacharyP 12/7/2011
由于地址国际化,这不再是有效的答案。请参阅 Mason 的回答。
16赞 Vladimir 1/12/2010 #2

你可以从维基百科的文章开始:

  • 大写和小写英文字母(a-z、A-Z)
  • 数字 0 到 9
  • 字符!# $ % & ' * + - / = ?^ _ ` { | } ~
  • 字符。(点、句点、句号)前提是它不是第一个或最后一个字符,并且还不得连续出现两次或更多次。
26赞 Mike Weller 1/12/2010 #3

维基百科上有一篇关于这方面的好文章官方规范在这里。来自Wikipdia:

电子邮件地址的本地部分可以使用以下任何 ASCII 字符:

  • 大写和小写英文字母(a-z、A-Z)
  • 数字 0 到 9
  • 字符!# $ % & ' * + - / = ?^ _ ` { | } ~
  • 字符。(点、句点、句号)前提是它不是第一个或最后一个字符,并且还不得连续出现两次或更多次。

此外,允许使用带引号的字符串(即:“John Doe”@example.com),从而允许使用原本被禁止的字符,但它们在通常的做法中不会出现。RFC 5321 还警告说,“期望接收邮件的主机应避免定义本地部分需要(或使用)带引号字符串形式的邮箱”。

评论

0赞 JensenDied 1/12/2010
@WildWezyr 有效的主机名,可以是 IP 地址、FQN 或可解析到本地网络主机的内容。
0赞 mckenzm 11/1/2018
带引号的琴弦对于通过网关是必不可少的,还记得榕树藤吗?
397赞 Mason 1/15/2010 #4

小心!这个线程中有一堆知识腐烂(过去是真的,现在不是)。

为了避免在当前和未来世界以及世界任何地方对实际电子邮件地址的误报拒绝,您至少需要了解 RFC 3490 的高级概念,即“应用程序中的域名国际化 (IDNA)”。我知道美国和澳大利亚的人们通常对此不感兴趣,但它已经在世界范围内广泛且迅速增加的使用(主要是非英语占主导地位的部分)。

要点是您现在可以使用mason@日本.com和 wildwezyr@fahrvergnügen.net 等地址。不,这还不能与所有的东西兼容(正如上面许多人所感叹的那样,即使是简单的 qmail 风格的 +ident 地址也经常被错误地拒绝)。但是有一个RFC,有一个规范,它现在得到了IETF和ICANN的支持,而且--更重要的是--目前有大量且越来越多的实施支持这一改进。

我自己对这个发展知之甚少,直到我搬回日本并开始看到像 hei@やる.ca 这样的电子邮件地址和这样的亚马逊 URL:

http://www.amazon.co.jp/ エレクトロニクス-デジタルカメラ-ポータブルオーディオ/b/ref=topnav_storetab_e?ie=UTF8&node=3210981

我知道你不想要规范的链接,但如果你仅仅依靠互联网论坛上黑客的过时知识,你的电子邮件验证器最终会拒绝非英语用户越来越期望工作的电子邮件地址。对于这些用户来说,这种验证将和我们都讨厌的司空见惯的脑死亡形式一样烦人,这种形式无法处理 + 或三部分域名或其他任何东西。

所以我并不是说这不是一个麻烦,但“在某些/任何/无条件下允许”的完整字符列表(几乎)是所有语言的所有字符。如果你想“接受所有有效的电子邮件地址(也有很多无效的)”,那么你必须考虑 IDN,这基本上使基于字符的方法变得毫无用处(对不起),除非你首先将国际化的电子邮件地址(自 2015 年 9 月以来已经死了,以前是这样的——一个有效的替代方案在这里)到 Punycode

完成此操作后,您可以遵循上述(大部分)建议。

评论

20赞 Mason 1/15/2010
右;在幕后,域名仍然只是 ASCII。但是,如果您的 Web 应用或表单接受用户输入的输入,则它需要执行与用户输入 IDN 主机名时 Web 浏览器或邮件客户端相同的工作:将用户输入转换为与 DNS 兼容的表单。然后验证。否则,这些国际化电子邮件地址将无法通过您的验证。(像我链接的转换器只修改它们给出的非 ASCII 字符,因此在非国际化电子邮件地址上使用它们是安全的(这些地址只是未经修改地返回)。
3赞 wwaawaw 10/7/2012
对于Javascript开发人员,我现在正在研究这样做的方法,而Punycode.js似乎是最完整,最完善的解决方案。
5赞 IMSoP 5/27/2014
请注意,国际化电子邮件(当前定义)不会使用 punycode 或类似代码转换非 ASCII 地址,而是扩展 SMTP 协议本身的大部分内容以使用 UTF8。
4赞 Samuel Harmer 2/6/2017
我是否遗漏了什么,或者这无法回答问题?我正在阅读“另一个答案是错误的,您需要接受更多字符”,但随后未能说明哪些额外的字符。我也无法(轻松)在该 RFC 中看到它是否意味着所有 Unicode 码位或仅意味着 BMP。
3赞 Sean 3/18/2017
这似乎是正确的答案。我敢打赌,如果你包括有关保留和允许字符的细节,它会得到更多的投票。
8赞 ThinkingStiff 1/18/2012 #5

名字:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`{|}~.

服务器:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.

评论

5赞 kenorb 8/5/2016
和呢?例如 {}|~.a“@example.org'?<>[]"()<>[]:,;@\\\"!#$%&'-/=?^_
23赞 Mathieu K. 2/15/2017
请注明出处。没有消息来源,这看起来像是猜想。
17赞 Jason Harrison 11/16/2017
这已经过时了,而且可能永远不正确。
13赞 Angel Koh 1/18/2012 #6

谷歌用他们的 gmail.com 地址做了一件有趣的事情。 gmail.com 地址只允许字母 (a-z)、数字和句点(被忽略)。

例如,[email protected] 与 [email protected] 相同,两个电子邮件地址将被发送到同一个邮箱。 [email protected] 也被传送到同一个邮箱。

因此,要回答这个问题,有时这取决于实施者想要遵循多少 RFC 标准。Google 的 gmail.com 地址样式与标准兼容。他们这样做是为了避免混淆,因为不同的人会使用相似的电子邮件地址,例如

*** gmail.com accepting rules ***
[email protected]   (accepted)
[email protected]   (bounce and account can never be created)
[email protected]     (accepted)
D.Oy'[email protected]   (bounce and account can never be created)

维基百科链接是电子邮件地址通常允许的良好参考。http://en.wikipedia.org/wiki/Email_address

评论

3赞 Piotr Kula 7/15/2014
是的,这是一个很好的答案,说明为什么Gmail不允许使用此功能创建电子邮件。但是您可以毫无问题地发送和接收电子邮件。也使用hMail服务器进行了测试。{john'doe}@my.server
0赞 Piotr Kula 7/15/2014
您可以通过发送电子邮件来测试您的客户 - 如果它有效,您将收到一个很好的自动回复。否则什么都不会发生。{piotr'kula}@kula.solutions
3赞 Teemu Leisti 1/20/2015
Gmail 确实遵循 RFC 6530,因为根据 RFC,Gmail 允许的每个可能的电子邮件地址都是有效的。Gmail只是选择使用其他规则进一步限制允许的地址集,并使本地部分带有点的类似地址(可选地后跟“+”和字母数字字符)成为同义词。
0赞 BradChesney79 2/9/2018
Google 限制了帐户创建标准...我想他们会清除传入电子邮件帐户字符串中的额外“标点符号”和尾随加上前缀别名字符串符号,以便将邮件路由到正确的帐户。简单易行。在这样做的过程中,他们实际上不允许人们创建只是混蛋的电子邮件地址,因此创建的有效地址通常会通过简单和最复杂的验证。
0赞 mckenzm 12/6/2018
不仅仅是 gmail,一些提供商具有“中继过滤器”,可以拒绝某些带引号的字符串,特别是包含“=”,就好像它们是分隔符一样。这是为了阻止用户设置网关和嵌套垃圾邮件地址在专用引号字符串中。“@”有效,但“=@=”(被认为)无效。
7赞 Michael JAMES 3/1/2012 #7

简短的回答是有 2 个答案。你应该做什么有一个标准,即明智的行为,会让你远离麻烦。对于你应该接受的行为,还有另一个(更广泛的)标准,而不会惹麻烦。这种二元性适用于发送和接受电子邮件,但在生活中有广泛的应用。

对于您创建的地址的良好指南;请参见:https://www.jochentopf.com/email/chars.html

要过滤有效的电子邮件,只需传递任何足以理解的内容即可查看下一步。 或者开始阅读一堆 RFC,注意,这里是龙。

评论

1赞 ygoe 5/26/2019
链接消失了。那里有什么内容?
0赞 MilMike 6/18/2021
@ygoe是的,网站已关闭,这是 ~2012 年的存档版本:web.archive.org/web/20120807105804/https://www.remote.org/...
0赞 ygoe 6/23/2021
@MilMike 谢谢,从那里我找到了该页面的新 URL 并编辑了答案。
11赞 Richard Maxwell 6/12/2013 #8

选中 @ 和 。然后发送电子邮件供他们验证。

我仍然无法在互联网上 20% 的网站上使用我的 .name 电子邮件地址,因为有人搞砸了他们的电子邮件验证,或者因为它早于新地址的有效性。

评论

9赞 11/28/2013
甚至。不是绝对必要的;我听说过至少一个顶级域(特别是ua)的电子邮件地址的情况。地址是<名字>@ua -- 没有点!
0赞 Avamander 1/13/2018
这几乎是不搞砸验证的最简单方法,因为几乎所有事情都是允许的,如果不允许某些事情,收件人的服务器会让你知道。
-1赞 Yash Patel 3/21/2014 #9

可以在此维基百科链接中找到

电子邮件地址的本地部分可以使用以下任何 ASCII 字符:

  • 大写和小写拉丁字母 to 和 toAZaz;

  • digits 设置为09;

  • 特殊字符!#$%&'*+-/=?^_`{|}~;

  • dot ,前提是除非引用,否则它不是第一个或最后一个字符,并且除非引用,否则它不会连续出现(例如 是不允许的,但被允许);.[email protected]"John..Doe"@example.com

  • 空格和字符是有限制的(它们只允许在带引号的字符串内,如下文所述,此外,反斜杠或双引号前面必须有一个反斜杠);"(),:;<>@[\]

  • 允许在本地部分的两端使用括号进行注释;例如: 并且都等价于 。john.smith(comment)@example.com(comment)[email protected][email protected]

除了上述 ASCII 字符外,RFC 6531 还允许使用 U+007F 以上的国际字符(编码为 UTF-8),但邮件系统可能会限制在分配本地部件时使用的字符。

带引号的字符串可以作为局部部分中的点分隔实体存在,也可以当最外层引号是局部部分的最外层字符时存在(例如,或允许使用。反之,不是;两者都不是)。但是,不常用带引号的字符串和字符。RFC 5321 还警告说,“期望接收邮件的主机应避免定义本地部分需要(或使用)带引号字符串形式的邮箱”。abc."defghi"[email protected]"abcdefghixyz"@example.comabc"defghi"[email protected]abc\"def\"[email protected]

本地部分经过特殊处理 - 不区分大小写,应转发给域电子邮件管理员。从技术上讲,所有其他本地部件都区分大小写,因此并指定不同的邮箱;但是,许多组织将大写字母和小写字母视为等效字母。postmaster[email protected][email protected]

尽管在技术上有效的特殊字符范围很广;在实践中,组织、邮件服务、邮件服务器和邮件客户端通常不接受所有这些。例如,Windows Live Hotmail 只允许使用字母数字、点 ()、下划线 () 和连字符 () 创建电子邮件地址。常见的建议是避免使用一些特殊字符,以避免电子邮件被拒绝的风险。._-

-4赞 Mohammed 9/18/2014 #10

Gmail 只允许将 + 签名作为特殊字符,在某些情况下 (.) 但 Gmail 不允许使用任何其他特殊字符。RFC说你可以使用特殊字符,但你应该避免用特殊字符向Gmail发送邮件。

4赞 Luke Madhanga 1/7/2015 #11

关于此事的好书。

摘录:

These are all valid email addresses!

"Abc\@def"@example.com
"Fred Bloggs"@example.com
"Joe\\Blow"@example.com
"Abc@def"@example.com
customer/[email protected]
\$A1[email protected]
!def!xyz%[email protected]
[email protected]

评论

1赞 Saiyaff Farouk 3/16/2017
我想知道域部分之前的“@”。可以使用吗?
0赞 Luke Madhanga 3/17/2017
@SaiyaffFarouk根据规格,是的。但是,大多数邮件提供商可能不允许将其作为自己验证的一部分
0赞 wesinat0r 4/22/2020
该博客列表没有引号。这真的有效吗?鉴于这里的答案似乎并不清楚,但我之所以问,是因为我见过包含反斜杠的 DNS SoA rname 电子邮件字符串的(非常罕见的)案例。Joe.\\[email protected]
-1赞 user2350426 6/21/2015 #12

答案是(几乎)(7 位 ASCII)。
如果包含规则为“......在某些/任何/无条件下允许......”
ALL

只需查看第 17 页顶部 RFC 5322 中“域文本”部分中允许文本的几个可能包含规则之一,我们就会发现:

dtext          =   %d33-90 /          ; Printable US-ASCII
                   %d94-126 /         ;  characters not including
                   obs-dtext          ;  "[", "]", or "\"

此描述中仅缺少的三个字符用于 domain-literal ,以形成带引号的对和空格字符 (%d32)。这样,整个范围 32-126(十进制)被使用。类似的要求显示为“qtext”和“ctext”。还允许/使用许多控制字符。RFC 5322 第 31 页第 4.1 节中显示此类控制字符的一个列表,称为 obs-NO-WS-CTL。[]\

obs-NO-WS-CTL  =   %d1-8 /            ; US-ASCII control
                   %d11 /             ;  characters that do not
                   %d12 /             ;  include the carriage
                   %d14-31 /          ;  return, line feed, and
                   %d127              ;  white space characters

所有此类控制字符都是允许的,如第 3.5 节开头所述:

.... MAY be used, the use of US-ASCII control characters (values
     1 through 8, 11, 12, and 14 through 31) is discouraged ....

因此,这样的纳入规则“太宽泛了”。或者,从另一个意义上说,预期的规则“过于简单”。

-2赞 Yevgeniy Afanasyev 7/23/2015 #13

在我的PHP中,我使用此检查

<?php
if (preg_match(
'/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[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_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/',
"tim'[email protected]"        
)){
    echo "legit email";
} else {
    echo "NOT legit email";
}
?>

自己试试 http://phpfiddle.org/main/code/9av6-d10r

13赞 Mac 12/5/2015 #14

在讨论电子邮件地址的有效本地部分时,公认的答案指的是维基百科的一篇文章,但维基百科不是这方面的权威。

IETF RFC 3696 这方面的权威,应在第 3 节中查阅。第 5 页对电子邮件地址的限制

当代电子邮件地址由一个“本地部分”组成,该部分与 由AT符号(“@”)组成的“域部分”(完全限定的域名)。 域部分的语法与前面的语法相对应 部分。该部分中确定的有关筛选和 名称列表适用于电子邮件上下文中使用的域名,如 井。域名也可以替换为 IP 地址 方括号,但强烈建议不要使用这种形式,但 出于测试和故障排除目的。

本地部分可能使用所描述的引用约定出现 下面。引用的表格在实践中很少使用,但必须 出于某些合法目的。因此,它们不应被拒绝 过滤例程,但应改为传递给电子邮件系统 供目标主机评估。

确切的规则是任何 ASCII 字符,包括控件 字符,可能以带引号的形式出现,也可能以带引号的字符串形式出现。当引用是 needed,则使用反斜杠字符来引用以下内容 字符。例如

  Abc\@[email protected]

是电子邮件地址的有效形式。也可能出现空白, 如

  Fred\ [email protected]

反斜杠字符也可用于引用自身,例如,

  Joe.\\[email protected]

除了使用反斜杠字符引用外,常规的 双引号字符可用于将字符串括起来。例如

  "Abc@def"@example.com

  "Fred Bloggs"@example.com

是上述前两个示例的替代形式。这些引用 很少推荐使用表格,并且在实践中并不常见,但是,作为 如上所述,必须由正在处理的应用程序支持 电子邮件地址。特别是,引用的形式经常出现在 与从其他系统转换关联的地址上下文 和上下文;这些过渡性要求仍然会出现,而且, 由于接受用户提供的电子邮件地址的系统不能 “知道”该地址是否与遗留系统相关联, 地址表单必须被接受并传递到电子邮件环境中。

如果没有引号,本地零件可以由以下任意组合组成 字母字符、数字或任何特殊字符

  ! # $ % & ' * + - / = ?  ^ _ ` . { | } ~

句点 (“.”) 也可能出现,但不能用于开始或结束 局部部分,也不得出现两个或多个连续的句点。 换言之,除 AT 符号 (“@”)、反斜杠、双引号、逗号或方括号 可能不带引号。如果该列表中的任何一项被排除在外 要出现字符,必须引用它们。形式,例如

  [email protected]

  customer/[email protected]

  [email protected]

  !def!xyz%[email protected]

  [email protected]

是有效的,并且经常出现,但任何字符 上面列出的是允许的。

正如其他人所做的那样,我提交了一个适用于 PHP 和 JavaScript 的正则表达式来验证电子邮件地址:

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

评论

1赞 Cromax 3/8/2023
从技术上讲,TLD 也允许使用电子邮件地址,因此您可以考虑将上一组的电子邮件地址更改为 .OTOH,TLD 中技术上有效的地址可能是一个空白的错别字,因为这些地址远不那么常见。规格与寿命... ;-)+*
0赞 Mac 3/11/2023
@Cromax - 没错。在我们能做什么和通常做什么之间必须有一个快乐的媒介。
-2赞 BradChesney79 1/24/2016 #15

为了简单起见,我在验证之前删除了双引号内的所有文本以及双引号周围的相关文本,根据不允许的内容将 kibosh 放在电子邮件地址提交上,从而对提交的内容进行了清理。仅仅因为有人可以拥有约翰......”*$hizzle*Bizzle“[email protected] 地址并不意味着我必须允许它进入我的系统。我们生活在未来,获得免费电子邮件地址可能比擦屁股花更少的时间。而且,这并不是说电子邮件标准没有贴在输入旁边,说明什么是允许的,什么是不允许的。

在删除引用的材料后,我还对各种 RFC 明确不允许的内容进行消毒。明确禁止的字符和模式列表似乎是一个要测试的更短的列表。

禁止:

    local part starts with a period ( [email protected] )
    local part ends with a period   ( [email protected] )
    two or more periods in series   ( [email protected] )
    &’`*|/                          ( some&thing`[email protected] )
    more than one @                 ( which@[email protected] )
    :%                              ( mo:characters%mo:[email protected] )

在给出的示例中:

John.."The*$hizzle*Bizzle"[email protected] --> [email protected]

[email protected] --> [email protected]

在尝试添加或更改电子邮件地址时向剩余结果发送确认电子邮件是查看代码是否可以处理提交的电子邮件地址的好方法。如果电子邮件在需要的多轮清理后通过了验证,则触发该确认。如果请求从确认链接返回,则可以从保留中移动新电子邮件||临时||炼狱状态或存储成为真正的、真正的一流存储电子邮件。

如果您想考虑,可以向旧电子邮件地址发送电子邮件地址更改失败或成功的通知。未经确认的帐户设置可能会在合理的时间后完全失败的尝试退出系统。

我不允许在我的系统上发送臭洞电子邮件,也许这只是在浪费钱。但是,99.9% 的时间人们只是做正确的事情,并且拥有一封不会利用边缘情况兼容性场景将一致性限制推向边缘的电子邮件。小心正则表达式 DDoS,这是一个您可能会遇到麻烦的地方。这与我做的第三件事有关,我限制了我愿意处理任何一封电子邮件的时间。如果它需要减慢我的机器速度才能得到验证,它不会通过我的传入数据 API 端点逻辑。

编辑:这个答案一直被指责为“坏”,也许这是应得的。也许它仍然很糟糕,也许不是。

评论

2赞 vcarel 6/8/2018
我认为这个答案被否决了,因为这是一个意见,它实际上没有回答这个问题。此外,静默清理电子邮件地址的用户将永远不会收到您的电子邮件。您最好通知他们不接受他们的电子邮件地址。
2赞 HoldOffHunger 9/11/2018
我怀疑投反对票是因为这里的想法太多了。不允许的列表虽然是有用的单元测试,但应以允许的内容开头。编程方法似乎相对较好,但是,在列出您正在使用的规范等之后,可能会更合适。章节和温和的文案编辑会有所帮助。只有我的 2 美分。
0赞 BradChesney79 9/11/2018
@vcarel - 哦,当然。前端用户端验证将告知他们违反了哪些规则(可从工具提示获得)。你是对的——这是一个总体意见。但是,上面的问题来自某个人,他肯定会向 X 询问 Y 问题。这是指导,它有效......它不仅有效,而且效果很好。我不会让废话的电子邮件地址出现在我做出决定的系统中。
0赞 BradChesney79 9/11/2018
@HoldOffHunger我能看到整体想法没有尽可能连贯地表达出来,我可能会在另一天修改,因为我有更多时间更好地表达这一点。感谢您的见解。
105赞 kenorb 8/5/2016 #16

电子邮件地址的格式为:(最多 64@255 个字符,总共不超过 256 个字符)。local-part@domain-part

和 可以有不同的允许字符集,但这还不是全部,因为它有更多的规则。local-partdomain-part

通常,本地部分可以包含以下 ASCII 字符:

  • 小写拉丁字母: ,abcdefghijklmnopqrstuvwxyz
  • 大写拉丁字母: ,ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • 数字:0123456789
  • 特殊字符: ,!#$%&'*+-/=?^_`{|}~
  • dot:(除非引用,否则不是第一个或最后一个字符或重复),.
  • 空格标点符号,例如:(有一些限制),"(),:;<>@[\]
  • 注释:(允许在括号内使用,例如 )。()(comment)[email protected]

领域部分:

  • 小写拉丁字母: ,abcdefghijklmnopqrstuvwxyz
  • 大写拉丁字母: ,ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • 数字:0123456789
  • 连字符:(不是第一个或最后一个字符),-
  • 可以包含用方括号括起来的 IP 地址:或 。jsmith@[192.168.2.1]jsmith@[IPv6:2001:db8::1]

以下电子邮件地址有效:

而这些无效的例子:

  • Abc.example.com(无字符)@
  • A@b@[email protected](只允许在引号外使用一个)@
  • a"b(c)d,e:f;gi[j\k][email protected](此本地部分中的任何特殊字符都不允许在引号外使用)
  • just"not"[email protected](带引号的字符串必须以点分隔或构成局部部分的唯一元素)
  • this is"not\[email protected](空格、引号和反斜杠可能仅在带引号的字符串内且前面有反斜杠时才存在)
  • this\ still\"not\[email protected](即使转义(前面有反斜杠),空格、引号和反斜杠仍必须由引号包含)
  • [email protected](双点前);(注意:Gmail 允许这样做)@
  • [email protected](双点后@)
  • 带有前导空格的有效地址
  • 带有尾随空格的有效地址

资料来源:维基百科的电子邮件地址


Perl 用于验证电子邮件的RFC2822正则表达式:

(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:
\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ 
\t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\
](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:
(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)
?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[
 \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t]
)*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
 \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*
)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)
*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r
\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](
?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?
:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] 
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(
?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t
])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?
:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)
?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)
?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[
 \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]
)*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:
\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])
*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\
.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(
?:\r\n)?[ \t])*))*)?;\s*)

RFC2822地址的完整正则表达式仅为 3.7k。

参见:PHP 中的 RFC 822 电子邮件地址解析器


电子邮件地址的正式定义如下:

  • RFC 5322(第 3.2.3 和 3.4.1 节,已过时的 RFC 2822)、RFC 5321、RFC 3696、
  • RFC 6531(允许的字符)。

相关:

评论

23赞 Chris Sobolewski 9/7/2017
作为对这个正则表达式的潜在实现者的额外警告:不要。只需验证它是否符合格式并收工即可。[email protected]
1赞 unjankify 2/28/2018
虽然这样的东西是不可维护的,但解码并实际弄清楚它的作用是一个很好的练习
9赞 tomuxmon 6/14/2019
我说疯狂。谁会在生产中使用它。在某种程度上,不应再使用正则表达式。它远远超出了这一点。
3赞 Synchro 9/18/2020
我经常看到的是“根据 RFC822 进行验证”。这实际上不是通常需要的。RFC822 没有定义可以发送到的地址;它定义了可以出现在消息中的地址,这不是一回事。可以发送到的地址在 RFC821 (SMTP) 和后续标准中确定。特别是,此规范不允许注释,不包括像这样的地址是有效的 RFC822 地址,但不能发送到。出于这个原因,许多电子邮件验证器正在针对错误的东西进行验证。a@abc(bananas)def.com
1赞 WoJ 9/8/2023
@ChrisSobolewski绝对的。此验证的目的是帮助用户,并避免明显的错误(例如忘记@或类似错误)。对电子邮件进行拆分并检查它是否返回两个非零字符串就足够了。@
-3赞 Mau 4/20/2017 #17

我根据 RFC 指南创建了这个正则表达式:

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

评论

1赞 Mau 5/20/2017
此版本通过检查域/子域的长度来改进正则表达式。享受!^[\\w\\.\\!_\\%#\\$\\&\\'=\\?\*\\+\\-\\/\\^\'\\{\\|\\}\\~]+@(?:[\\w](?:[\\w\\-]{0,61}[\\w])?(?:\\.[\\w](?:[\\w\\-]{0,61}[\\w])?)*)$
2赞 ThinkTrans 7/7/2022 #18

很多人已经尝试回答这个问题。很多人还说,许多答案已经过时了。这是我的答案,因为 2022 年的情况。

这个问题的答案显然并不像人们提出的那么简单。在这种情况下,当涉及到邮箱名称的命名时,具体来说,<用户名>的拟议标准以及对这些 RFC 的解释是很多的。

对于<用户名>部分,普遍适用性指导小组在一份名为 UASG-028 的文档中提出了一个详细的指南,说明哪些内容构成了电子邮件 ID 本地部分。

对于<服务器>部分,此处提到的“应用程序的 Unicode 代码点和国际化域名 (IDNA)”中提到的所有字符,字符状态为“PVALID”。此外,状态为“CONTEXTJ”和“CONTEXTO”的字符在某些连续条件下有效。