电子邮件地址中允许使用什么字符?


639

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

我只想知道电子邮件地址中允许使用的字符user-name以及server部分内容。这可能被简化了,也许电子邮件地址可以采用其他形式,但是我不在乎。我只问这种简单的形式:(user-name@server例如wild.wezyr@best-server-ever.com)并在两个部分都允许使用字符。


184
+被允许的。当网站不允许它时,我会发疯,因为我的电子邮件中包含+,并且很多站点都不允许它。
丹·赫伯特

42
我认为,提供指向规范的链接非常重要,因为您确实想正确地做到这一点,而规范正是在其中出现的。如果您懒于阅读和理解规范,请保留检查电子邮件地址中允许的字符给那些关心这种东西的人。
jhwist 2010年

9
涉及相同材料的早期问题:stackoverflow.com/questions/760150/。可悲的是,即使这个问题比这个问题大了将近8个月,但这个老问题却有更好的答案。以下几乎所有答案最初都已经过时。请参阅Wikipedia条目(不用担心,它具有相关的官方参考资料)。
约翰Y

10
相反,几个答案,空格允许的电子邮件地址的本地部分,如果引用。"hello world"@example.com已验证。
user253751 2014年

3
@LaraRuffleColes-对于Gmail,创建电子邮件帐户时,不允许您创建包含“ +”号的地址。“ +”号(“加地址”)允许具有Gmail地址的任何人在其用户名末尾添加“ +”号,后跟“字符串”,以创建“替代”(“别名”)电子邮件地址用于他们的帐户。例如:“ example@gmail.com”,“ example+tag@gmail.com”。通常(可能是“主要”)的用法是能够为您的帐户创建别名电子邮件地址,从而使您可以标记和过滤从理论上说由发件人过滤的传入电子邮件。
凯文·费根

Answers:


797

请参阅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字符:

  • AZa到的大写和小写拉丁字母z;
  • 数字09;
  • 特殊字符!#$%&'*+-/=?^_`{|}~;
  • dot .,除非它不是第一个或最后一个字符,除非被引用,并且除非被引用,否则它不会连续出现(例如John..Doe@example.com,不允许但"John..Doe"@example.com被允许);
  • 空格和"(),:;<>@[\]字符是有限制的(如下文所述,只能在带引号的字符串中使用,此外,反斜杠或双引号之前必须带有反斜杠);
  • 注释可以在局部的任何一端加上括号;例如john.smith(comment)@example.com(comment)john.smith@example.com都等同于john.smith@example.com

除ASCII字符外,从2012年起,您还可以使用上述 国际字符U+007F,这些字符按照RFC 6532规范中的说明编码为UTF-8,并在Wikipedia上进行了说明。请注意,截至2019年,这些标准仍被标记为“提议中”,但进展缓慢。此规范的更改实质上将国际字符添加为有效的字母数字字符(atext),而不会影响关于允许和限制的特殊字符(例如!#和)的规则@:

要进行验证,请参阅使用正则表达式来验证电子邮件地址

domain部分定义如下

Internet标准(征求意见)的协议,授权该组件的主机名的标签可能只包含ASCII字母a,通过z(在不区分大小写),数字09和连字符(-)。RFC 952中主机名的原始规范要求标签不能以数字或连字符开头,并且不能以连字符结尾。但是,随后的规范(RFC 1123)允许主机名标签以数字开头。不允许使用其他符号,标点符号或空格。


15
@WildWzyr,不是那么简单。电子邮件地址对于允许的内容有很多规则。引用规范比列出所有规范更简单。如果您需要完整的正则表达式,请查看此处了解为什么它不是那么简单:regular-expressions.info/email.html
Dan Herbert,2010年

6
没有简单的清单,仅仅是因为您想要简单的东西并不意味着会如此。有些字符只能在某些位置,而不能在其他位置。您不可能一直都有想要的东西。

15
@WildWezyr好吧,本地部分允许使用句号。但不是开始或结束。或与另一个句号。因此,答案不只是列出允许的字符那么简单,还有关于如何使用这些字符的规则- .ann..other.@example.com不是有效的电子邮件地址,但ann.other@example.com即使两个都使用相同的字符,也是如此。
Mark Pim 2010年

14
另外,请记住,随着国际化域名的到来,允许的字符列表将会爆炸。
Chinmay Kanchi 2010年

50
由于国际化的地址,这不再是有效的答案。请参阅梅森的答案。
ZacharyP 2011年

329

小心!该线程中有很多知识腐烂(过去是正确的东西,现在不是)。

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

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

我本人对这个发展不太了解,直到我回到日本并开始看到像hei @やる.ca这样的电子邮件地址和如下的Amazon URL:

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

我知道您不希望链接到规范,但是,如果您仅依靠Internet论坛上过时的黑客知识,则电子邮件验证程序最终将拒绝非英语用户越来越希望使用的电子邮件地址。对于那些用户来说,这种验证就像我们都讨厌的普通的脑残形式一样令人讨厌,这种形式不能处理+或三部分的域名或其他任何形式。

因此,我并不是说这不是一件麻烦事,但是“在某些/任何/无条件下允许使用的字符”的完整列表(几乎)是所有语言中的所有字符。如果要“接受所有有效的电子邮件地址(也包括许多无效的电子邮件地址)”,则必须考虑IDN,这基本上使基于字符的方法无用(对不起),除非您首先将国际化的电子邮件地址转换Punycode

之后,您可以遵循(大部分)上述建议。


17
对; 在幕后,域名仍然只是ASCII。但是,如果您的Web应用程序或表单接受用户输入的输入,则当用户输入IDN主机名时,它需要执行与Web浏览器或邮件客户端相同的工作:将用户输入转换为DNS兼容形式。然后验证。否则,这些国际化的电子邮件地址将不会通过您的验证。(像我这样链接的转换器只修改了给定的非ASCII字符,因此可以在非国际化的电子邮件地址上使用它们(将它们返回而未修改)是安全的。)
Mason 2010年

2
对于Javascript开发人员,我现在正在研究执行此操作的方法,Punycode.js似乎是最完整和完善的解决方案。
wwaawaw 2012年

5
请注意,国际化电子邮件(当前定义)不会使用punycode或类似方法转换非ASCII地址,而是将SMTP协议本身的大部分扩展为使用UTF8。
IMSoP 2014年

2
我错过了什么吗?还是无法回答这个问题?我在读“另一个答案是错误的,您需要接受更多字符”,但随后却没有说明哪些额外的字符。我也无法(轻松地)在RFC中看到它是指所有Unicode代码点还是BMP。
塞缪尔·哈默

3
这似乎是正确答案的正确道路。我敢打赌,如果您包含有关保留字符和允许字符的详细信息,它将获得更多的选票。
肖恩

59

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

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

通常,本地部分可以具有以下ASCII字符:

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

域部分:

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

这些电子邮件地址有效:

  • prettyandsimple@example.com
  • very.common@example.com
  • disposable.style.email.with+symbol@example.com
  • other.email-with-dash@example.com
  • x@example.com (一个字母的局部)
  • "much.more unusual"@example.com
  • "very.unusual.@.unusual.com"@example.com
  • "very.(),:;<>[]\".VERY.\"very@\ \"very\".unusual"@strange.example.com
  • example-indeed@strange-example.com
  • admin@mailserver1 (没有顶级域的本地域名)
  • #!$%&'*+-/=?^_`{}|~@example.org
  • "()<>[]:,;@\\"!#$%&'-/=?^_`{}| ~.a"@example.org
  • " "@example.org (引号之间的空格)
  • example@localhost (从本地主机发送)
  • example@s.solutions(请参阅Internet顶级域列表
  • user@com
  • user@localserver
  • user@[IPv6:2001:db8::1]

这些例子无效:

  • Abc.example.com(无@字符)
  • A@b@c@example.com(除@引号外只允许使用一个)
  • a"b(c)d,e:f;gi[j\k]l@example.com (此引号中的任何特殊字符都不能被引号引起来)
  • just"not"right@example.com (带引号的字符串必须用点分隔,或组成局部的唯一元素)
  • this is"not\allowed@example.com (空格,引号和反斜杠仅在带引号的字符串中并且以反斜杠开头时才可能存在)
  • this\ still\"not\allowed@example.com (即使已转义(以反斜杠开头),空格,引号和反斜杠仍必须包含在引号中)
  • john..doe@example.com(之前的双点@);(警告:Gmail允许通过此操作)
  • john.doe@example..com(后面的双点@
  • 有效地址,带前导空格
  • 有尾随空格的有效地址

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


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(允许的字符)。

有关:


5
对正则表达式的实施者要特别注意:不要。只需验证它遵循该格式something@something.something并命名为“ day”即可。
克里斯·索博洛夫斯基

尽管这样的事情无法维护,但解码并真正弄清楚它的作用是一个不错的练习
取消混淆

@ChrisSobolewski允许'@'两侧有多个东西
Jasen

我已经尝试在check_recipient_access限制下通过pcre访问表在postfix中实现此功能,首先将3个长pcres(来自链接页面)分别变成一行,并以此作为开头和结尾:/^[...pcre ..] $ / DUNNO,然后添加最后一行/.*/ REJECT,但是它仍然允许通过无效的电子邮件地址。后缀3.3.0; perl 5,版本26,Subversion 1(v5.26.1)。
scoobydoo

3
我说疯了。谁会在生产中使用它。有一点应该不再使用正则表达式。这远远超出了这一点。
tomuxmon

22

维基百科对此有很好的文章官方规格在这里。从维基百科:

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

  • 大写和小写英文字母(az,AZ)
  • 数字0至9
  • 人物!#$%&'* +-/ =?^ _`{| }〜
  • 性格。(点,句号,句号),前提是它不是第一个字符或最后一个字符,并且还不能连续出现两次或多次。

另外,允许使用带引号的字符串(例如:“ John Doe” @ example.com),从而允许使用其他方式禁止使用的字符,但是在常规情况下不会出现这些字符。RFC 5321还警告“希望接收邮件的主机应避免在本地部分需要(或使用)引号字符串形式的情况下定义邮箱”。


@WildWezyr有效的主机名,可以是ip地址,FQN或本地网络主机可以解析的名称。
Jensen死于2010年

引号的字符串对于通过网关至关重要,还记得Banyan Vines吗?
mckenzm

13

Google用gmail.com地址做一件有趣的事情。gmail.com地址仅允许使用字母(az),数字和句点(被忽略)。

例如,pikachu@gmail.com与pi.kachu@gmail.com相同,并且两个电子邮件地址都将发送到同一邮箱。PIKACHU@gmail.com也传递到同一邮箱。

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

*** gmail.com accepting rules ***
d.oy.smith@gmail.com   (accepted)
d_oy_smith@gmail.com   (bounce and account can never be created)
doysmith@gmail.com     (accepted)
D.Oy'Smith@gmail.com   (bounce and account can never be created)

Wikipedia链接是通常允许的电子邮件地址的很好的参考。 http://en.wikipedia.org/wiki/电子邮件地址


2
是的,对于为什么Gmail不允许使用此方法创建电子邮件,这是一个很好的答案。但是您可以{john'doe}@my.server毫无问题地发送和接收电子邮件。也通过hMail服务器进行了测试。
Piotr Kula 2014年

您可以通过发送电子邮件至来测试您的客户{piotr'kula}@kula.solutions-如果可以,您会收到一封不错的自动回复邮件。否则,将不会发生任何事情。
Piotr Kula 2014年

3
Gmail确实遵循RFC 6530,因为Gmail允许的每个可能的电子邮件地址都根据RFC有效。Gmail只是选择通过其他规则进一步限制允许的地址集,并在本地部分中使用点名(否则可以加上“ +”和字母数字字符作为同义词)来创建其他类似的地址。
Teemu Leisti 2015年

Google限制了帐户创建标准...我想他们会清理传入的电子邮件帐户中多余的“标点符号”和结尾加上前缀的别名字符串符号,以便可以将邮件路由到正确的帐户。十分简单。在这样做时,它们实际上不允许人们创建一个简直是垃圾邮件的电子邮件地址,因此创建的有效地址通常会通过简单和最复杂的验证。
BradChesney79 '18

不只是gmail,某些提供程序还具有“中继过滤器”,可以拒绝某些带引号的字符串,尤其是包含“ =”时,就好像它们是分隔符一样。这是为了阻止用户设置网关并将垃圾邮件地址嵌套在带引号的私有字符串中。“ @”有效,但“ = @ =”无效(被认为)。
mckenzm

12

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

  • 大写和小写英文字母(az,AZ)
  • 数字0至9
  • 人物!#$%&'* +-/ =?^ _`{| }〜
  • 性格。(点,句号,句号),前提是它不是第一个字符或最后一个字符,并且还不能连续出现两次或多次。

11

名称:

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

服务器:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.

4
怎么样<>[]?例如"()<>[]:,;@\\\"!#$%&'-/=?^_{} |
〜.a

20
请引用消息来源。没有消息来源,这看起来像是猜测。
Mathieu K.

15
这已经过时了,可能永远都不正确。
杰森·哈里森

9

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

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


9
甚至。并非绝对必要;我听说过至少一个顶级域(特别是ua)电子邮件地址的情况。地址为<名称> @ua-无点!

这几乎是不搞乱验证的最简单方法,因为几乎所有内容都是允许的,并且如果不允许某些内容,则收件人的服务器会通知您。
Avamander

5

简短的答案是有2个答案。您应该做什么有一个标准。即明智的行为,将使您摆脱麻烦。还有另一种(更广泛的)标准来规定您应该接受的行为而不会造成麻烦。这种双重性适用于发送和接受电子邮件,但在生活中具有广泛的应用。

为您提供创建地址的良好指南;参见:http : //www.remote.org/jochen/mail/info/chars.html

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


链接不见了。那里有什么内容?
伊戈

5

关于这个问题的好阅读。

摘抄:

These are all valid email addresses!

"Abc\@def"@example.com
"Fred Bloggs"@example.com
"Joe\\Blow"@example.com
"Abc@def"@example.com
customer/department=shipping@example.com
\$A12345@example.com
!def!xyz%abc@example.com
_somename@example.com

1
我想知道域部分之前的“ @”。可以使用吗?
Saiyaff Farouk

@SaiyaffFarouk根据规范,是的。但是,大多数邮件提供商可能不允许将其作为自己进行验证的一部分
Luke Madhanga

该博客列表Joe.\\Blow@example.com不带引号。这真的有效吗?给出的答案似乎还不清楚,但是我问,是因为我已经看到(非常罕见的)DNS SoA rname电子邮件字符串包含反斜杠的情况。
wesinat0r

5

讨论电子邮件地址的有效本地部分时,可接受的答案是Wikipedia的文章,但Wikipedia并非对此的授权。

IETF RFC 3696 此问题的授权机构,应在第3节中进行参考。第5页上的电子邮件地址限制

现代电子邮件地址包含一个“本地部分”,该“本地部分”与“域部分”(全限定域名)之间用一个符号(“ @”)隔开。域部分的语法与上一节中的语法相对应。在该部分中确定的有关过滤和名称列表的问题也适用于电子邮件上下文中使用的域名。域名也可以用方括号中的IP地址代替,但是强烈建议不要使用这种形式,除非出于测试和故障排除的目的。

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

确切的规则是,任何ASCII字符(包括控制字符)都可能出现在带引号的地方或带引号的字符串中。当需要引用时,反斜杠字符用于引用以下字符。例如

  Abc\@def@example.com

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

  Fred\ Bloggs@example.com

反斜杠字符也可以用于引号本身,例如,

  Joe.\\Blow@example.com

除了使用反斜杠字符进行引用之外,常规的双引号字符也可以用于包围字符串。例如

  "Abc@def"@example.com

  "Fred Bloggs"@example.com

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

不带引号的本地部分可以由
字母字符,数字或任何特殊字符的任意组合组成

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

句点(“。”)也可能会出现,但可能不会用于开始或结束本地部分,也不会出现两个或多个连续的句点。换句话说,除符号(“ @”),反斜杠,双引号,逗号或方括号之外的任何ASCII图形(打印)字符都可能会出现而不加引号。如果要显示任何排除字符列表,则必须用引号引起来。形式如

  user+mailbox@example.com

  customer/department=shipping@example.com

  $A12345@example.com

  !def!xyz%abc@example.com

  _somename@example.com

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

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

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

3

可以在此Wikipedia链接中找到

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

  • AZa到的大写和小写拉丁字母z;

  • 数字09;

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

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

  • 空格和"(),:;<>@[\]字符是有限制的(如下文所述,只能在带引号的字符串中使用,此外,反斜杠或双引号之前必须带有反斜杠);

  • 注释可以在局部的任何一端加上括号;例如john.smith(comment)@example.com(comment)john.smith@example.com都等同于john.smith@example.com

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

带引号的字符串可以作为局部部分内的点分隔实体存在,或者当最外面的引号是局部部分的最外层字符时(例如,abc."defghi".xyz@example.com"abcdefghixyz"@example.com允许,反之abc"defghi"xyz@example.com则不是;也不是abc\"def\"ghi@example.com),它可以存在。但是,带引号的字符串和字符并不常用。RFC 5321还警告“希望接收邮件的主机应避免在本地部分需要(或使用)引号字符串形式的情况下定义邮箱”。

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

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


0

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

只需查看第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 ....

因此,这种包含规则“太宽”了。或者,换句话说,期望的规则是“太简单了”。


0

为简单起见,我通过在验证之前删除双引号中的所有文本和与之相关的双引号来对提交进行消毒,然后根据不允许的情况将其放在电子邮件地址提交上。仅仅因为有人可以拥有John ..“ The * $ hizzle * Bizzle” .. Doe@whatever.com地址并不意味着我必须在我的系统中允许它。我们生活在未来,获得免费电子邮件地址所花的时间可能比做好擦屁股的时间要少。并不是说输入的内容旁边没有显示电子邮件条件,而是说什么是允许的和不允许的。

在删除引用的材料后,我还将清除各种RFC明确不允许的内容。明确禁止使用的字符和模式的列表似乎要简短得多。

不允许:

    local part starts with a period ( .account@host.com )
    local part ends with a period   ( account.@host.com )
    two or more periods in series   ( lots..of...dots@host.com )
    &’`*|/                          ( some&thing`bad@host.com )
    more than one @                 ( which@one@host.com )
    :%                              ( mo:characters%mo:problems@host.com )

在给出的示例中:

John.."The*$hizzle*Bizzle"..Doe@whatever.com --> John..Doe@whatever.com

John..Doe@whatever.com --> John.Doe@whatever.com

尝试添加或更改电子邮件地址时,向剩余的结果发送确认电子邮件是查看代码是否可以处理提交的电子邮件地址的好方法。如果电子邮件在根据需要进行了多轮消毒之后通过了验证,则请取消该确认。如果请求从确认链接返回,则可以将新电子邮件从保存状态或存储中移出,成为真实,真实的一流存储电子邮件。

如果您想体贴,可以将电子邮件地址更改失败或成功的通知发送到旧电子邮件地址。未确认的帐户设置可能会在合理的时间后完全失败,因为尝试失败。

我不允许在我的系统上发送恶臭的电子邮件,也许那只是浪费钱。但是,有99.9%的时间人们只是在做正确的事情,并且收到一封电子邮件,没有利用边缘案例的兼容性场景将合规性限制推高到极限。注意正则表达式DDoS,这是您可能会遇到麻烦的地方。这与我要做的第三件事有关,我限制了我愿意处理任何一封电子邮件的时间。如果它需要减慢我的机器的速度以进行验证-它不会超出我的传入数据API端点逻辑。

编辑:这个答案一直因“坏”而感到羞愧,也许它应该得到它。也许仍然很糟糕,也许不是。


2
我认为这个答案不可行,因为这是一种意见,实际上并不能回答问题。此外,对用户的电子邮件地址进行静默处理的用户将永远不会收到您的电子邮件。您最好通知他们,他们的电子邮件地址不被接受。
vcarel

2
我怀疑投票否定是因为这里有太多想法。禁止列表虽然是有用的单元测试,但应在允许的范围内开始。编程方法似乎相对不错,但是在列出要使用的规范等之后,它可能会更适合。部分内容和适当的复制编辑会有所帮助。就是我的2美分。
HoldOffHunger

@vcarel-哦,绝对。前端用户端验证将告知他们违反了哪些规则(可从工具提示中获得)。您是对的-这是一个整体意见。但是,上面的问题确实来自某个正在向X询问Y问题的人。这是指导并且有效...不仅有效,而且效果很好。我不会在我做决定的系统中放任何胡扯的电子邮件地址。
BradChesney79 2016年

@HoldOffHunger我可以看到总体想法没有得到尽可能一致的表达,我可能会在另一天进行修改,因为我有更多的时间来更好地表达它。感谢您的见解。
BradChesney79 2011年

-1

在我的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'qqq@gmail.com"        
)){
    echo "legit email";
} else {
    echo "NOT legit email";
}
?>

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


-1

我根据RFC准则创建了此正则表达式:

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

1
此版本通过检查域/子域的长度来改进正则表达式。请享用!^ [\\ w \\。\\!_ \\%#\\ $$ \\&\\'= \\?\ * \\\ + \\-\\\\\\ ^ \`\\ {\\ | \\} \\〜] + @(?:[\\ w](?:[\\ w \\-] {0,61} [\\ w])?(?:\\。[\\ w](?:[\\ w \\-] {0,61} [\\ w])?)*)$
Mau

-2

Gmail仅允许使用+号作为特殊字符,在某些情况下(。),但Gmail不允许使用任何其他特殊字符。RFC表示您可以使用特殊字符,但应避免使用特殊字符向Gmail发送邮件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.