ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

+ 是允许的。当网站不允许它时,它让我发疯,因为我的电子邮件中有一个 + 并且很多网站都不允许它。
涉及相同材料的较早问题:stackoverflow.com/questions/760150/。可悲的是,即使这个问题比这个问题早了将近 8 个月,旧问题的答案要好得多。以下几乎所有答案在最初发布时已经过时。请参阅 Wikipedia entry(别担心,它有相关的 official references)。
与几个答案相反,如果引用,电子邮件地址的本地部分中允许使用空格"hello world"@example.com 有效。
@LaraRuffleColes - 对于 Gmail,当您创建电子邮件帐户时,它不允许您创建包含“+”号的地址。 “+”号(“加号”)允许拥有 Gmail 地址的任何人在其用户名末尾添加“+”号后跟“字符串”,以创建“备用”(“别名”)电子邮件地址用于他们的帐户。示例:“example@gmail.com”、“example+tag@gmail.com”。一个典型的(可能是“主要”)使用是能够为您的帐户创建别名电子邮件地址,允许您标记和过滤传入的电子邮件,理论上由发件人过滤。
@Andrew反过来更常见。如果一个网站不能被信任以允许正确的电子邮件地址,我不相信他们会处理我的个人信息。

C
Community

请参阅 RFC 5322: Internet Message Format,在较小程度上,请参阅 RFC 5321: Simple Mail Transfer Protocol

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

和往常一样,维基百科有一个不错的 article on email addresses

电子邮件地址的本地部分可以使用以下任何 ASCII 字符:大写和小写拉丁字母 A 到 Z 和 a 到 z;数字 0 到 9;特殊字符 !#$%&'*+-/=?^_`{|}~;点 .,前提是它不是第一个或最后一个字符,除非被引用,并且它不连续出现,除非被引用(例如 John..Doe@example.com 是不允许的,但 "John..Doe"@example. com 是允许的);空格和 "(),:;<>@[\] 字符是允许的,但有限制(它们只允许在带引号的字符串中,如下段所述,此外,反斜杠或双引号必须以反斜杠);注释允许在本地部分的任一端加上括号;例如 john.smith(comment)@example.com 和 (comment)john.smith@example.com 都等价于 john.smith@example。 com。

除了 ASCII 字符之外,as of 2012 您还可以使用国际 characters above U+007F,编码为 UTF-8,如 RFC 6532 spec 中所述并在 Wikipedia 中解释。请注意,截至 2019 年,这些标准仍被标记为已提议,但正在缓慢推出。本规范中的更改基本上将国际字符添加为有效的字母数字字符(atext),而不会影响允许的 & 规则。受限制的特殊字符,例如 !#@:

有关验证,请参阅 Using a regular expression to validate an email address

domain 部分定义为 as follows

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


@WildWzyr,没那么简单。电子邮件地址对允许的内容有很多规则。参考规范比列出所有规范更简单。如果您想要完整的正则表达式,请查看此处了解为什么它不那么简单:regular-expressions.info/email.html
没有简单的清单,仅仅因为你想要简单的东西并不意味着它会如此。某些字符只能在某些位置,而不能在其他位置。你不可能一直拥有你想要的。
@WildWezyr好吧,本地部分允许使用句号字符。但不是在开始或结束。或者用另一个句号。所以答案并不像允许的字符列表那么简单,关于如何使用这些字符有一些规则 - .ann..other.@example.com 不是有效的电子邮件地址,但 ann.other@example.com 是,即使两者都使用相同的字符.
另外,请记住,随着国际化域名的出现,允许的字符列表将会爆炸。
由于地址国际化,这不再是有效的答案。见梅森的回答。
D
David Veszelovszki

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

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

要点是您现在可以使用 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,这基本上使基于字符的方法无用(抱歉),除非您首先 convert the internationalized email addresses(自 2015 年 9 月起死亡,以前是 like this——一个可行的替代方法是 here) 到 Punycode

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


正确的;在幕后,域名仍然只是 ASCII。但是,如果您的 Web 应用程序或表单接受用户输入的输入,则它需要执行与用户输入 IDN 主机名时 Web 浏览器或邮件客户端相同的工作:将用户输入转换为与 DNS 兼容的表单。然后验证。否则,这些国际化的电子邮件地址将无法通过您的验证。 (像我链接的转换器只修改给定的非 ASCII 字符,因此在非国际化电子邮件地址上使用它们是安全的(这些只是未经修改返回)。)
对于 Javascript 开发人员,我现在正在研究这样做的方法,Punycode.js 似乎是最完整和最完善的解决方案。
请注意,国际化电子邮件(如当前定义)不使用 punycode 或类似代码转换非 ASCII 地址,而是将 SMTP 协议本身的大部分扩展为使用 UTF8。
我错过了什么还是无法回答问题?我正在阅读“另一个答案是错误的,您需要接受更多字符”,但随后未能说明哪些额外字符。我也无法(轻松地)在该 RFC 中看到它是指所有 Unicode 代码点还是仅指 BMP。
这似乎是正确答案的正确轨道。我敢打赌,如果您包含有关保留和允许字符的详细信息,它将获得更多选票。
k
kenorb

电子邮件地址的格式为: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

一次性.style.email.with+symbol@example.com

other.email-with-dash@example.com

x@example.com(一个字母的本地部分)

“非常不寻常”@example.com

“非常.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(引号之间的空格)

示例@localhost(从本地主机发送)

example@s.solutions(参见 Internet 顶级域列表)

用户@com

用户@本地服务器

用户@[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(@ 后的双点)

带有前导空格的有效地址

带有尾随空格的有效地址

来源:维基百科的Email address

Perl's RFC2822 regex 用于验证电子邮件:

(?:(?:\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。

另请参阅:RFC 822 Email Address Parser in PHP

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

RFC 5322(第 3.2.3 和 3.4.1 节,已过时的 RFC 2822)、RFC 5321、RFC 3696、

RFC 6531(允许的字符)。

有关的:

正则表达式的真正威力


作为对这个正则表达式的潜在实施者的额外警告:不要。只需验证它是否遵循格式 something@something.something 并收工。
虽然这样的事情是不可维护的,但它是一个很好的练习来解码并实际弄清楚它的作用
@ChrisSobolewski 允许在“@”的两边使用多个东西
我说疯了。谁会在生产中使用它。有一点应该不再使用正则表达式。它远远超出了这一点。
我经常看到的是“根据 RFC822 进行验证”。这实际上不是通常需要的。 RFC822 没有定义可以发送到的地址;它定义了可以出现在消息中的地址,这不是一回事。可以发送到的地址在 RFC821 (SMTP) 和后续标准中确定。特别是该规范不允许注释,不包括像 a@abc(bananas)def.com 这样的有效 RFC822 地址但不能发送到的地址。出于这个原因,许多电子邮件验证器正在验证错误的东西。
C
Community

Wikipedia has a good article on thisthe official spec is here。来自维基百科:

电子邮件地址的本地部分可以使用以下任何 ASCII 字符: 大写和小写英文字母 (az, AZ) 数字 0 到 9 个字符! # $ % & ' * + - / = ? ^ _ ` { | } ~ 字符。 (点、句号、句号)只要它不是第一个或最后一个字符,并且它不连续出现两次或多次。此外,允许使用带引号的字符串(即:“John Doe”@example.com),从而允许原本被禁止的字符,但它们不会出现在常见的实践中。 RFC 5321 还警告说“希望接收邮件的主机应该避免定义本地部分需要(或使用)引用字符串形式的邮箱”。


@WildWezyr 有效的主机名,可以是 IP 地址、FQN 或可解析到本地网络主机的东西。
带引号的字符串对于通过网关至关重要,还记得 Banyan Vines 吗?
V
Vladimir

您可以从 wikipedia article 开始:

大写和小写英文字母(az、AZ)

数字 0 到 9

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

特点 。 (点、句号、句号)只要它不是第一个或最后一个字符,并且它不连续出现两次或多次。


g
gaoithe

谷歌用他们的 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)

维基百科链接是关于通常允许使用哪些电子邮件地址的一个很好的参考。 http://en.wikipedia.org/wiki/Email_address


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

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

IETF RFC 3696是有关此事的权威,应在第 3 节进行咨询。第 5 页的电子邮件地址限制

现代电子邮件地址由“本地部分”与“域部分”(完全限定的域名)通过 at 符号(“@”)分隔。域部分的语法对应于上一节中的语法。该部分中确定的有关过滤和名称列表的问题也适用于电子邮件上下文中使用的域名。域名也可以用方括号中的 IP 地址替换,但强烈建议不要使用这种形式,除非用于测试和故障排除目的。本地部分可能会使用下面描述的引用约定出现。引用的表格在实践中很少使用,但出于某些合法目的是必需的。因此,它们不应在过滤例程中被拒绝,而应被传递到电子邮件系统以供目标主机评估。确切的规则是任何 ASCII 字符,包括控制字符,都可以出现在引号中,或者出现在带引号的字符串中。当需要引用时,反斜杠字符用于引用后面的字符。例如 Abc\@def@example.com 是电子邮件地址的有效形式。也可能出现空格,如 Fred\ Bloggs@example.com 反斜杠字符也可用于引用自身,例如 Joe.\\Blow@example.com 除了使用反斜杠字符进行引用外,传统的双引号字符可用于包围字符串。例如,“Abc@def”@example.com “Fred Bloggs”@example.com 是上述前两个示例的替代形式。这些引用的表单很少被推荐,并且在实践中并不常见,但是,如上所述,必须得到处理电子邮件地址的应用程序的支持。特别是,引用的形式经常出现在与来自其他系统和上下文的转换相关的地址上下文中;这些过渡性要求仍然存在,并且由于接受用户提供的电子邮件地址的系统无法“知道”该地址是否与旧系统相关联,因此必须接受地址表格并将其传递到电子邮件环境中。如果没有引号,本地部分可以由字母字符、数字或任何特殊字符的任意组合组成! # $ % & ' * + - / = ? ^_`。 { | } ~ period (".") 也可能出现,但不能用于开始或结束本地部分,也不能出现两个或多个连续的句点。换句话说,除 at 符号 ("@")、反斜杠、双引号、逗号或方括号之外的任何 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

T
ThinkingStiff

姓名:

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

服务器:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.

<>[] 呢?例如 "()<>[]:,;@\\\"!#$%&'-/=?^_{}| ~.a"@example.org`?
请引用来源。没有来源,这看起来像是猜想。
这已经过时了,而且可能永远都不正确。
R
Richard Maxwell

检查 @ 和 .然后发邮件给他们验证。

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


甚至 。不是绝对必要的;我听说过至少一个顶级域(特别是 ua)的电子邮件地址案例。地址是 @ua -- 没有点!
这几乎是不搞砸验证的最简单方法,因为几乎所有事情都是允许的,如果某些事情是不允许的,收件人的服务器会通知你。
y
ygoe

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

有关您创建的地址的良好指南;见:https://www.jochentopf.com/email/chars.html

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


链接不见了。有什么内容?
@ygoe 是的,网站已关闭,这是 ~2012 年的存档版本:web.archive.org/web/20120807105804/https://www.remote.org/…
@MilMike 谢谢,从那里我找到了该页面的新 URL 并编辑了答案。
B
Billal Begueradj

matter 上的好读物。

摘抄:

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

我想知道域部分之前的“@”。那可以用吗?
@SaiyaffFarouk 根据规范,是的。但是,大多数邮件提供商可能不会允许将其作为自己验证的一部分
该博客列出了不带引号的 Joe.\\Blow@example.com。这真的有效吗?给出这里的答案似乎还不清楚,但我之所以问,是因为我已经看到(非常罕见)包含反斜杠的 DNS SoA rname 电子邮件字符串的情况。
C
Community

可以在 this Wikipedia link 中找到

电子邮件地址的本地部分可以使用以下任何 ASCII 字符:大写和小写拉丁字母 A 到 Z 和 a 到 z;数字 0 到 9;特殊字符 !#$%&'*+-/=?^_`{|}~;点 .,前提是它不是第一个或最后一个字符,除非被引用,并且它不连续出现,除非被引用(例如 John..Doe@example.com 是不允许的,但 "John..Doe"@example. com 是允许的);空格和 "(),:;<>@[\] 字符是允许的,但有限制(它们只允许在带引号的字符串中,如下段所述,此外,反斜杠或双引号必须以反斜杠);注释允许在本地部分的任一端加上括号;例如 john.smith(comment)@example.com 和 (comment)john.smith@example.com 都等价于 john.smith@example。 com. 除了上述 ASCII 字符之外,U+007F 以上的国际字符,编码为 UTF-8,在 RFC 6531 中是允许的,尽管邮件系统在分配本地部分时可能会限制使用哪些字符。带引号的字符串可能存在为本地部分中的点分隔实体,或者当最外层引号是本地部分的最外层字符时它可能存在(例如,abc."defghi".xyz@example.com 或 "abcdefghixyz"@example.com 是允许。相反,abc"defghi"xyz@example.com 不是;abc\"def\"ghi@example.com 也不是。但是,带引号的字符串和字符不是t 常用。 RFC 5321 还警告说“希望接收邮件的主机应该避免定义本地部分需要(或使用)引用字符串形式的邮箱”。 local-part postmaster 被特殊处理——它不区分大小写,并且应该转发给域电子邮件管理员。从技术上讲,所有其他本地部分都区分大小写,因此 jsmith@example.com 和 JSmith@example.com 指定不同的邮箱;但是,许多组织将大写和小写字母视为等价的。尽管有大量的特殊字符在技术上是有效的;组织、邮件服务、邮件服务器和邮件客户端在实践中通常不接受所有这些。例如,Windows Live Hotmail 仅允许使用字母数字、点 (.)、下划线 (_) 和连字符 (-) 创建电子邮件地址。常见的建议是避免使用一些特殊字符来避免电子邮件被拒绝的风险。


C
Community

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

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

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

此描述中仅有的三个缺失字符用于域文字 [],以形成引号对 \,以及空白字符 (%d32)。使用整个范围 32-126(十进制)。类似的要求显示为“qtext”和“ctext”。许多控制字符也被允许/使用。此类控制字符的一个列表显示在第 31 页 section 4.1 of RFC 5322 中,为 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 ....

因此,这样的包含规则“太宽泛了”。或者,在其他意义上,预期的规则“过于简单化”。


B
BradChesney79

为简单起见,我通过在验证之前删除双引号内的所有文本以及相关的双引号周围的文本来清理提交,根据不允许的内容将 kibosh 放在电子邮件地址提交上。仅仅因为有人可以拥有 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 - 哦,绝对。前端用户端验证将告知他们他们违反了哪些规则(可从工具提示中获得)。你是对的——这是一个总体意见。但是,上面的问题来自某个肯定会向 X 询问 Y 问题的人。这是指导,它有效……它不仅有效,而且运作良好。我不会让我做决定的系统中出现胡说八道的电子邮件地址。
@HoldOffHunger 我可以看到整体想法并没有像它可能的那样连贯地表达,我可能会在另一天进行修改,以便我有更多时间更好地表达这一点。感谢您的洞察力。
T
ThinkTrans

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

这个问题的答案显然不像已经提出的那么简单。关于邮箱名称命名的提议标准,具体而言, 在这种情况下,以及对这些 RFC 的解释很多。

对于<用户名>部分,普遍接受性指导小组在此处标题为 UASG-028 的文档中就构成电子邮件 ID 本地部分的所有内容提出了详细指南。

对于<服务器>部分,这里提到的所有字符“The Unicode Code Points and Internationalized Domain Names for Applications (IDNA)”,字符状态为“PVALID”。此外,状态为“CONTEXTJ”和“CONTEXTO”的字符在某些上下文条件下有效。


Y
Yevgeniy Afanasyev

在我的 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


M
Mau

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

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

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

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