正则表达式匹配电子邮件[重复]

问题描述 投票:3回答:4

我需要一个与电子邮件地址匹配的正则表达式,本地@域具有以下要求:

局部部分可以包含A-z,0-9,点,下划线和短划线。

域可以包含A-z,0-9,点和破折号。域需要包含至少一个点。

我如何确保:域不能以点或破折号开头或结尾。并且域需要包含至少一个点?

这两件事确实让我在尝试解决它时遇到了问题。

尝试了以下内容:

Regex.IsMatch(email, @"(?:[^.-])([\w.-])@([\w.-])(?:[.-]$)");
c# regex
4个回答
7
投票

正确答案是:

ONLY validate that @ is present, the domain portion matches a few simple rules, the local part is <= 64 characters, and the whole thing is <= 254 characters.

是的,排除完全非法的字符,好的。并确保使用最后的@符号,而不是第一个。有关有效域名的所有商品,请参阅RFC 1035。也许RFC 819可以提供帮助。

如果您使用的是HTML,那么只需使用电子邮件输入<input type="email" autocomplete="off" autocorrect="off">,您将获得浏览器本身强制执行的大部分正确的东西,而您无需做任何工作。见email input validation at MDN。虽然请注意,根据浏览器的不同,即使这样也可能过于严格。请参阅this bug,其中浏览器的正确行为是接受电子邮件地址中的unicode(接受IDN标签),然后执行从U标签到​​A标签的转换,然后才执行验证。

如果您愿意,也可以检查是否可以在DNS中找到域,但这是一个不必要且费力的步骤。

为什么我用巨幅印刷品大喊大叫呢?因为如此。臭。许多网站完全和可怕的错误。

首先,请阅读:I Knew How To Validate An Email Address Until I Read The RFC

然后,跟我说理片刻。鉴于,正如文章所说:

  1. 除了关于@符号的基本规则,各个部分的长度以及完全禁止的字符之外,电子邮件地址是否有效的唯一确定者是该电子邮件地址的发行者 - 域所有者。
  2. 确定电子邮件地址是否实际到达任何人的唯一决定因素是向该地址发送电子邮件,并查看该人是否获得该电子邮件地址。

想想邮件。让我们假设有人给你一个有趣的地址,比如说,这个:

AAB!129 Thor Circle 1/2 atomized Pile$
Armelioborrigenduliamo, GRICKL, θ-niner *
18957382:90347342;21017900~19127734.6
THE MOON

既然您以前可能从未向月球发送邮件,您是否确定要按照您熟悉的地区标准判断月球邮件地址?你怎么知道这不是一个有效的地址?如果这些人真的很奇怪怎么办?如果您是一家计划与您的客户做生意并且赚取大量资金的公司 - 为什么他们会关心地址是否只要地址有效就很奇怪?

事实上,美国的标准商业惯例证明了这种无法验证其他权威机构地址的现实:邮政地址清理。这意味着,当有人向您提交邮寄地址时,您会向美国邮政局发送API调用,询问这是否是有效地址,并进一步询问其规范形式。那是因为只有邮局可以告诉你地址是否有效。即便如此,在你尝试发送一封信之前,你不知道你的信是否会传给任何人!

那么,为什么你会如此推定,以至于拒绝某人使用一个完全有效的电子邮件地址,他们的电子邮件提供商知道它是有效的(类似于向另一个国家甚至另一个星球发送邮件),只是因为它有某种格式你'不习惯或你无知认为是错的?

如果您只是因为拼写错误而试图避免收到错误的电子邮件地址,那么您仍然可以这样做。向用户显示“嘿,关于你的地址的东西看起来不太正确。你确定它包含你选择的这些字符吗?!#$%^&*()”{} []`〜请记住,如果我们无法通过电子邮件发送给您,您无法创建帐户。“然后人们会收到警告,但如果他们真的想要,他们仍然可以提交。(好吧,是的,排除完全禁止的字符。我列出的是不一定有效。查一查。你应该仔细查看。真的。你不应该接受一些随机网络人士的话。了解。)

继续,甚至让它有点痛苦 - 让他们提交两次。或者选中一个方框并再次提交。只是不要阻止他们使用他们想要的任何东西。

我个人有时决定不使用无法接受本地部分(在@之前)加号的电子邮件地址的网站或服务。如果我只是必须拥有帐户,我会咬牙切齿,有点生气,然后提交一个与我真正想要使用的地址不同的地址。

除非您真的想减少可以与之合作的客户群。然后继续进行限制......

Okay, at this point, you hate me

你以为我反应过度了。您只想验证您的电子邮件地址!会这么难吗?事实上,你只是会忽略我并继续写下一个能完成这项工作的人。这够好了。

好吧。如果你不听理由,那么here's some regex for you that does it right。 (只是,我实际上并不知道它是否正确,但是我愿意打赌它是一个更接近正确的视线,而不是任何人在不到几天和几天内自己想出的任何东西工作的。)

神奇的电子邮件验证正则表达式

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

当然,它已被打破。删除换行符。


1
投票

在一种黑暗和自我毁灭的疯狂中,我决定回答你的问题。

您的确切要求:

  • 局部部分可以包含A-z,0-9,点,下划线和短划线。
  • 域可以包含A-z,0-9,点和破折号。
  • 域需要包含至少一个点。
  • 域名不能以点或破折号开头或结尾。

您的RegEx满足这些确切要求而不再是(不区分大小写的匹配):

^[\w.-]+@(?=[a-z\d][^.]*\.)[a-z\d.-]*[^.]$

Try it out at regex101.com

我小心翼翼地确保这几乎没有回溯。在regex101.com,您可以看到它执行了多少步骤。好地址有13个步骤验证,非常好。在末尾带点的地址是性能最差的,因为这会导致整个域部分一次回溯一个字符,但它们可能很少见。

请在这篇文章中投票,就像你对其他试图回答问题的帖子进行投票一样。

然后,看看我的其他answer on this page并投票。

笔记:

在C#中,\w包括a wide range of Unicode characters。这可能是也可能不是你想要的。如果没有,您可以按原样保留Regex并使用符合ECMAScript标准的模式。或者,您可以将其更改为a-z0-9_(方括号内)。但\w更短。

\dincludes some additional numeric characters

\ d匹配任何十进制数字。它等同于\ p {Nd}正则表达式模式,它包括标准的十进制数字0-9以及许多其他字符集的十进制数字。

您可以再次使用ECMAScript兼容模式,或者只需将其更改为0-9。但\d更短。

请注意,这个正则表达式不好有很多有用的方法。它允许域部分中的IP地址(不正确),它不限制正则表达式的总长度或域部分的长度。它不正确地限制了不应该限制的本地部分的字符。它根本不是一个好的规范。


0
投票

编辑

我认为这会奏效:

Regex regex = new Regex(@"^([\w\.\-]+)@((?!\.|\-)[\w\-]+)((\.(\w){2,3})+)$");

注意:域名不能包含点和空格

但是,您可以尝试使用Mail Address Class而不是使用正则表达式。这样你就不必为理解别人的正则表达而挣扎

public bool IsEmailValid(string address)
{
    try
    {
        MailAddress m = new MailAddress(address);
        return true;
    }
    catch (FormatException)
    {
       return false;
    }
}

0
投票

你应该从http://www.regular-expressions.info这样的来源学习正则表达式 - 到目前为止尝试显示了很多缺失的知识,并且所述的问题非常复杂(甚至忽略了自定义正则表达式几乎肯定是错误的方法,尽管它可能是一个有用的预处理过滤)。

为什么这个正则表达式不起作用 - @"(?:[^.-])([\w.-])@([\w.-])(?:[.-]$)");

我将通过将正则表达式分解为英语来解释(这对于正则表达式来说通常是一种很棒的技术):

首先,这里的所有括号都没有功能,所以我忽略了它们(请参阅教程,了解它们的含义)

本地

  • [^.-] - 1个不是点或短划线的角色
  • [\w.-] - 1个字母,字母数字或点或短划线

因此,local的定义是以2个字符串结尾并具有上述约束的任何字符串。

@ - 文字,字符'@'

  • [\w.-] - 1个字母,字母数字或点或短划线
  • [.-] - 1个字符,是点或短划线
  • $ - 字符串的结尾。

因此,域的定义是具有上述约束的2字符串。

这显然与给定问题相差甚远。

什么是满足给定约束的正则表达式?

实际上,正则表达式依次左右评估。在一组连续的描述中表达您的约束,然后将它们转换为正则表达式结构。我会为了给定的约束(我认为不完整)这样做。在每条线之间精神上插入一个'后跟'。

字符串的开头 - ^ - 表示字符串开头的正则表达方式

local - [\w._-]* - 任意数量的(字母数字,点,破折号)。

@ - @ - 文字字符

关键要求是至少1个点。此点将明确显示在正则表达式中,因此将域视为{preDot} {dot} {postDot}。为简单起见,将{dot}定义为.的第一次出现。

  • \w - 单个字母数字字符 - 这不是以点或短划线要求开头的
  • [\w-]* - 字母数字或短划线的任意数量的字符
  • \. - 单个(第一个)点字符 - 这是特殊必须存在的点
  • (\w*[\.-])* - 任意数量(任意数量的字母数字字符,后跟点或短划线)
  • [\w-]+ - 一个或多个字母数字或短划线字符 - 这是必须以点要求结束

字符串结尾 - $ - 表示字符串结尾的正则表达方式

这是相应的代码:

var literal = @"\w*";

var preDot = @"\w[\w-]*";
var dot = @"\.";
var postDot = @"(\w*[\.-])*[\w-]+";
var domain = $"{preDot}{dot}{postDot}";

var email = $"^{literal}@{domain}$";

仅供参考 - 正则表达式最终成为^\w*@\w[\w-]*\.(\w*[\.-])*[\w-]+$,但这在很大程度上是无关紧要的,尝试理解/维护/改变它作为一个单独的字符串是可怕的,而故障是可以遵循的。

© www.soinside.com 2019 - 2024. All rights reserved.