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

848

我并不是在问如何完整验证电子邮件。

我只想知道电子邮件地址中用户名服务器部分允许使用哪些字符。这可能有些简化了,也许电子邮件地址可以采用其他形式,但我不关心。我只是询问这个简单的形式:用户名@服务器(例如 wild.wezyr@best-server-ever.com),并且两部分允许使用哪些字符。


264
“+”符号是允许的。当网站不允许“+”符号时,我会感到很烦,因为我的电子邮件地址里有一个“+”符号,而许多网站都不允许使用它。 - Dan Herbert
12
之前有类似的问题:stackoverflow.com/questions/760150/。悲哀的是,尽管那个问题比这个早了近8个月,但那个问题的答案要好得多。几乎所有下面的答案在最初发布时就已经过时了。请参阅 维基百科条目(不用担心,它有相关的官方参考资料)。 - John Y
29
与一些答案相反,如果加上引号,电子邮件地址的本地部分是允许包含空格的。例如,"hello world"@example.com 是合法的。 - user253751
11
当你创建一个Gmail邮箱时,它不允许你使用加号(+)符号来创建地址。加号符号(即正则表达式“Plus-addressing”)允许任何拥有Gmail地址的人在他们的用户名后面添加加号符号和字符串,以便创建一个用于他们账户的“备选”(“别名”)电子邮件地址。例如:“example@gmail.com”和“example+tag@gmail.com”。这种方法的一个典型(并且可能是“主要”)用途是为您的账户创建别名电子邮件地址,这些地址允许您标记和过滤传入的电子邮件信息,理论上可以通过发送者进行过滤。 - Kevin Fegan
10
反过来更为普遍。如果一个网站不能信任其允许的电子邮件地址是正确的,我就不相信他们能够妥善处理我的个人信息。 - Dan Herbert
显示剩余17条评论
18个回答

4

关于这个问题的好文章。

摘录:

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

3

已经有很多人尝试回答这个问题。也有很多人说很多答案已经过时了。以下是我在2022年的回答。

显然,这个问题的答案并不像它被提出的那么简单。具体来说,关于邮箱名称(在这个上下文中是<user-name>)的命名所提出的标准,以及这些RFC的解释,非常繁多。

对于<user-name>部分,通用接受管理组已在一份名为UASG-028的文件中提供了详细的指南,说明电子邮件ID本地部分包括哪些内容。

对于<server>部分,在此提到的所有字符“应用程序的Unicode代码点和国际化域名(IDNA)”都具有字符状态“PVALID”。此外,状态为“CONTEXTJ”和“CONTEXTO”的字符在某些上下文条件下也是有效的。


-1

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

仅通过查看RFC 5322页面17顶部中“域文本”部分中允许文本的多个可能包含规则之一,我们就可以找到:

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

这个描述中唯一缺失的三个字符用于 domain-literal [] 中,以形成一个 quoted-pair \ 和空格字符 (%d32)。因此整个范围 32-126(十进制)被使用。类似的要求出现在“qtext”和“ctext”中。许多控制字符也被允许/使用。这样的控制字符列表出现在第31页 RFC 5322的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 ....

这样的包含规则因此“太宽泛”了。或者换句话说,期望的规则“过于简单化”。


-1

可以在这个维基百科链接中找到。

电子邮件地址的 local-part 可以使用以下任何 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 字符外,RFC 6531 允许使用编码为 UTF-8 的 U+007F 以上的国际字符,虽然邮件系统可能会限制在分配 local-part 时使用哪些字符。
引号包含的字符串可以存在于 local-part 中的点分隔实体中,也可以存在于 local-part 的最外层字符为引号的情况下(例如 abc."defghi".xyz@example.com 或 "abcdefghixyz"@example.com 是允许的。相反,abc"defghi"xyz@example.com 和 abc\"def\"ghi@example.com 都不是。引号包含的字符串和字符是不常用的。RFC 5321 还警告说,“期望接收邮件的主机应避免定义需要(或使用)Quoted-string 格式的 Local-part 的邮箱”。 local-part postmaster 被特殊处理 - 它不区分大小写,并且应该转发给域电子邮件管理员。从技术上讲,所有其他 local-part 都区分大小写,因此 jsmith@example.com 和 JSmith@example.com 指定不同的邮箱;然而,许多组织将大写字母和小写字母视为等效。
尽管在技术上合法的特殊字符范围很广,但实际上,组织、邮件服务、邮件服务器和邮件客户端通常不接受所有这些字符。例如,Windows Live Hotmail 只允许使用字母数字、句点 (.)、下划线 (_) 和连字号 (-) 创建电子邮件地址。常见建议是避免使用某些特殊字符,以避免被拒绝的电子邮件的风险。

-2
为了简单起见,在验证之前,我会通过删除双引号内的所有文本以及与其相关联的双引号来清理提交内容,从而阻止基于不允许的内容提交的电子邮件地址。仅仅因为某人可以拥有像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
我怀疑这些负评是因为这里有太多的想法。虽然这些被禁止的列表是有用的单元测试,但应该先说明允许使用什么。编程方法似乎相对不错,但在列出你正在使用的规格等之后可能更适合。分节和轻微的编辑会有所帮助。这只是我的个人意见。 - HoldOffHunger
@vcarel - 当然。前端用户端验证会告诉他们他们正在违反哪些规则(可以从工具提示中获得)。你是对的 - 这是一个总体意见。然而,上面的问题来自于某人肯定在问X的Y问题。这是指导,它起作用...不仅起作用,而且效果很好。我不会让胡说八道的电子邮件地址进入我的系统,我做出决策。 - BradChesney79
@HoldOffHunger 我能看出整体想法表达得不够连贯,我可能会在另一个有更多时间的日子里进行修订,以更好地表达。感谢您的见解。 - BradChesney79

-2

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


-3

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

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

1
这个版本通过检查域名/子域名的长度来改进正则表达式。享受吧! ^[\w\.\!_\%#\$\&\'=\?\\+\-\/\^\`\{\|\}\~]+@(?:\w?(?:\.\w?))$ - Mau

-4

Gmail 仅允许使用加号 + 作为特殊字符,并且在某些情况下(.)也可以使用,但是其他任何特殊字符都不允许在 Gmail 中使用。RFC 规定可以使用特殊字符,但应避免向 Gmail 发送包含特殊字符的邮件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接