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

我只想知道电子邮件地址的用户名和服务器部分允许使用哪些字符。这可能过于简单化,也许电子邮件地址可以采取其他形式,但我不在乎。我只问这个简单的表格:user-name@server(例如。wild.wezyr@best-server-ever.com)以及两部分中允许的字符。


当前回答

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

本地部分和域部分可以有不同的允许字符集,但这还不够,因为它有更多的规则。

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

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

域部分:

小写拉丁字母:abcdefghijklmnopqrstuvxyz,大写拉丁字母:EFGHIJKLMNOPQRSTUVWXYZ,数字:0123456789,连字符:-(不是第一个或最后一个字符),可以包含由方括号包围的IP地址:jsmith@[1992.2.1]或jsmith@[IPv6:2001:db8::1]。

这些电子邮件地址有效:

prettyandsimple@example.comvery.common@example.com一次性样式邮件+symbol@example.comother.email-with-dash@example.comx@example.com(一个字母局部)“非常不寻常”@example.com"very.unusual.@.unusual.com“@example.com”“非常.(),:;<>[]\”.very.\“非常@\\”非常\“不寻常”@strange.example.comexample-indeed@strange-example.comadmin@mailserver1(没有顶级域的本地域名)#!$%&'*+-/=?^_`{}|~@example.org"()<>[]:,;@\\"!#$%&'-/=?^_`{}|~.a“@example.org“”@example.org(引号之间的空格)example@localhost(从本地主机发送)example@s.solutions(请参阅Internet顶级域列表)user@comuser@localserver用户@[IPv6:2001:db8::1]

以下是无效的示例:

Abc.example.com(无@字符)A@b@c@example.com(引号外只允许有一个@)a“b(c)d,e:f;gi[j\k]”l@example.com(本地部分中的任何特殊字符都不允许在引号外)只是“不”right@example.com(带引号的字符串必须以点分隔,或者是构成局部部分的唯一元素)这是“不”\allowed@example.com(空格、引号和反斜杠只能存在于带引号的字符串中且前面有反斜杠)这个“仍然”不是\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(允许的字符)。


相关:

正则表达式的真正威力

其他回答

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

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

为了简单起见,我在验证前删除了双引号内的所有文本以及与双引号相关的文本,并根据不允许的内容对电子邮件地址提交进行了过滤。只是因为有人可以拥有约翰。。“$$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%的人只是做了正确的事情,并且有一封电子邮件不会利用边缘案例兼容性场景将符合性限制推到边缘。小心regex DDoS,这是一个你可能会遇到麻烦的地方。这与我做的第三件事有关,我对处理任何一封电子邮件的时间设置了限制。如果它需要降低我的机器的速度以获得验证——它无法通过我的传入数据API端点逻辑。

编辑:这个回答一直被指责为“糟糕”,也许这是理所应当的。也许它仍然糟糕,也许不是。

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

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

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

本说明中仅有的三个缺失字符用于域文字[]中,以形成引号对\和空白字符(%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 ....

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

请参阅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;特殊字符!#$%&'*+-/=^_`{|}~;点前提是除非被引用,否则它不是第一个或最后一个字符,并且除非被引用(例如。John..Doe@example.com不允许,但允许使用“John…Doe”@example.com);空格和“(),:;<>@[\]字符允许有限制(它们只允许在带引号的字符串中,如下面的段落所述,此外,反斜杠或双引号前面必须有反斜杠);注释允许在本地部分的两端加括号;例如john.smith(注释)@example.com和(注释)john.smith@example.com都相当于john.smith@example.com.

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

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

域部分定义如下:

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

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

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