我不是在问完整的电子邮件验证。
我只想知道电子邮件地址中允许使用的字符user-name
以及server
部分内容。这可能被简化了,也许电子邮件地址可以采用其他形式,但是我不在乎。我只问这种简单的形式:(user-name@server
例如wild.wezyr@best-server-ever.com)并在两个部分都允许使用字符。
"hello world"@example.com
已验证。
我不是在问完整的电子邮件验证。
我只想知道电子邮件地址中允许使用的字符user-name
以及server
部分内容。这可能被简化了,也许电子邮件地址可以采用其他形式,但是我不在乎。我只问这种简单的形式:(user-name@server
例如wild.wezyr@best-server-ever.com)并在两个部分都允许使用字符。
"hello world"@example.com
已验证。
Answers:
请参阅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字符:
A
到Z
和a
到的大写和小写拉丁字母z
;- 数字
0
到9
;- 特殊字符
!#$%&'*+-/=?^_`{|}~
;- 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
(在不区分大小写),数字0
通9
和连字符(-
)。RFC 952中主机名的原始规范要求标签不能以数字或连字符开头,并且不能以连字符结尾。但是,随后的规范(RFC 1123)允许主机名标签以数字开头。不允许使用其他符号,标点符号或空格。
.ann..other.@example.com
不是有效的电子邮件地址,但ann.other@example.com
即使两个都使用相同的字符,也是如此。
小心!该线程中有很多知识腐烂(过去是正确的东西,现在不是)。
为了避免当前和未来世界以及世界上任何地方对实际电子邮件地址的误判拒绝,您至少需要了解RFC 3490的高级概念“应用程序中的域名国际化(IDNA)”。我知道美国和A的人通常对此并不满意,但是它已经在世界范围内广泛使用并迅速增加(主要是非英语为主的部分)。
要点是,您现在可以使用mason@Japan.com和wildwezyr@fahrvergnügen.net这样的地址。不,这还不能与所有内容兼容(正如上面许多人感叹的那样,即使简单的qmail样式+ ident地址也经常被错误地拒绝)。但是有一个RFC,有一个规范,它现在得到了IETF和ICANN的支持,而且更重要的是,目前有越来越多的实现这种改进的实施支持。
我本人对这个发展不太了解,直到我回到日本并开始看到像hei @やる.ca这样的电子邮件地址和如下的Amazon URL:
我知道您不希望链接到规范,但是,如果您仅依靠Internet论坛上过时的黑客知识,则电子邮件验证程序最终将拒绝非英语用户越来越希望使用的电子邮件地址。对于那些用户来说,这种验证就像我们都讨厌的普通的脑残形式一样令人讨厌,这种形式不能处理+或三部分的域名或其他任何形式。
因此,我并不是说这不是一件麻烦事,但是“在某些/任何/无条件下允许使用的字符”的完整列表(几乎)是所有语言中的所有字符。如果要“接受所有有效的电子邮件地址(也包括许多无效的电子邮件地址)”,则必须考虑IDN,这基本上使基于字符的方法无用(对不起),除非您首先将国际化的电子邮件地址转换为Punycode。
之后,您可以遵循(大部分)上述建议。
电子邮件地址的格式为:(local-part@domain-part
最多64 @ 255个字符,总共不超过256个)。
该local-part
和domain-part
可以有不同的一组允许的字符,但是这还不是全部,因为有更多的规则给它。
通常,本地部分可以具有以下ASCII字符:
abcdefghijklmnopqrstuvwxyz
,ABCDEFGHIJKLMNOPQRSTUVWXYZ
,0123456789
,!#$%&'*+-/=?^_`{|}~
,.
不是第一个或最后一个字符,除非有引号,否则不得重复),"(),:;<>@[\]
有一些限制),()
例如,允许在括号内(comment)john.smith@example.com
)。域部分:
abcdefghijklmnopqrstuvwxyz
,ABCDEFGHIJKLMNOPQRSTUVWXYZ
,0123456789
,-
不是第一个或最后一个字符),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电子邮件地址解析器。
电子邮件地址的正式定义在:
有关:
something@something.something
并命名为“ day”即可。
维基百科对此有很好的文章,官方规格在这里。从维基百科:
电子邮件地址的本地部分可以使用以下任何ASCII字符:
- 大写和小写英文字母(az,AZ)
- 数字0至9
- 人物!#$%&'* +-/ =?^ _`{| }〜
- 性格。(点,句号,句号),前提是它不是第一个字符或最后一个字符,并且还不能连续出现两次或多次。
另外,允许使用带引号的字符串(例如:“ John Doe” @ example.com),从而允许使用其他方式禁止使用的字符,但是在常规情况下不会出现这些字符。RFC 5321还警告“希望接收邮件的主机应避免在本地部分需要(或使用)引号字符串形式的情况下定义邮箱”。
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/电子邮件地址
{john'doe}@my.server
毫无问题地发送和接收电子邮件。也通过hMail服务器进行了测试。
{piotr'kula}@kula.solutions
-如果可以,您会收到一封不错的自动回复邮件。否则,将不会发生任何事情。
名称:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`{|}~.
服务器:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.
<>
和[]
?例如"()<>[]:,;@\\\"!#$%&'-/=?^_
{} |
简短的答案是有2个答案。您应该做什么有一个标准。即明智的行为,将使您摆脱麻烦。还有另一种(更广泛的)标准来规定您应该接受的行为而不会造成麻烦。这种双重性适用于发送和接受电子邮件,但在生活中具有广泛的应用。
为您提供创建地址的良好指南;参见:http : //www.remote.org/jochen/mail/info/chars.html
要过滤有效的电子邮件,只需传递任何易于理解的内容即可查看下一步。或开始阅读一堆RFC,注意,这里有些龙。
关于这个问题的好阅读。
摘抄:
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
Joe.\\Blow@example.com
不带引号。这真的有效吗?给出的答案似乎还不清楚,但是我问,是因为我已经看到(非常罕见的)DNS SoA rname电子邮件字符串包含反斜杠的情况。
讨论电子邮件地址的有效本地部分时,可接受的答案是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
可以在此Wikipedia链接中找到
电子邮件地址的本地部分可以使用以下任何ASCII字符:
A
到Z
和a
到的大写和小写拉丁字母z
;数字
0
到9
;特殊字符
!#$%&'*+-/=?^_`{|}~
;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仅允许使用字母数字,点(
.
),下划线(_
)和连字符(-
)创建电子邮件地址。常见建议是避免使用一些特殊字符,以免出现电子邮件被拒绝的风险。
答案是(几乎)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 ....
因此,这种包含规则“太宽”了。或者,换句话说,期望的规则是“太简单了”。
为简单起见,我通过在验证之前删除双引号中的所有文本和与之相关的双引号来对提交进行消毒,然后根据不允许的情况将其放在电子邮件地址提交上。仅仅因为有人可以拥有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端点逻辑。
编辑:这个答案一直因“坏”而感到羞愧,也许它应该得到它。也许仍然很糟糕,也许不是。
在我的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";
}
?>
我根据RFC准则创建了此正则表达式:
^[\\w\\.\\!_\\%#\\$\\&\\'=\\?\\*\\+\\-\\/\\^\\`\\{\\|\\}\\~]+@(?:\\w+\\.(?:\\w+\\-?)*)+$
+
被允许的。当网站不允许它时,我会发疯,因为我的电子邮件中包含+
,并且很多站点都不允许它。