用于验证电子邮件地址的 C# 代码
验证字符串是否为有效电子邮件地址的最优雅的代码是什么?
What is the most elegant code to validate that a string is a valid email address?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
验证字符串是否为有效电子邮件地址的最优雅的代码是什么?
What is the most elegant code to validate that a string is a valid email address?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(30)
这又如何呢?
根据 Stuart 的评论,这会将最终地址与原始字符串进行比较,而不是始终返回 true。 MailAddress 尝试将带有空格的字符串解析为“显示名称”和“地址”部分,因此原始版本返回误报。
为了澄清,问题是询问特定字符串是否是电子邮件地址的有效表示,而不是电子邮件地址是否是发送消息的有效目的地。为此,唯一真正的方法是发送消息进行确认。
请注意,电子邮件地址比您最初想象的更宽容。这些都是完全有效的形式:
对于大多数用例,错误的“无效”对于您的用户和未来的验证来说比错误的“有效”要糟糕得多。这是
提供健全性检查对于用户体验来说仍然是一个好主意。假设电子邮件地址有效,您可以查找已知的顶级域,检查域中的 MX 记录,检查常见域名 (gmail.cmo) 中的拼写错误等。然后向用户发出警告有机会说“是的,我的邮件服务器确实允许
What about this?
Per Stuart's comment, this compares the final address with the original string instead of always returning true. MailAddress tries to parse a string with spaces into "Display Name" and "Address" portions, so the original version was returning false positives.
To clarify, the question is asking whether a particular string is a valid representation of an e-mail address, not whether an e-mail address is a valid destination to send a message. For that, the only real way is to send a message to confirm.
Note that e-mail addresses are more forgiving than you might first assume. These are all perfectly valid forms:
For most use cases, a false "invalid" is much worse for your users and future proofing than a false "valid". Here's an article that used to be the accepted answer to this question (that answer has since been deleted). It has a lot more detail and some other ideas of how to solve the problem.
Providing sanity checks is still a good idea for user experience. Assuming the e-mail address is valid, you could look for known top-level domains, check the domain for an MX record, check for spelling errors from common domain names (gmail.cmo), etc. Then present a warning giving the user a chance to say "yes, my mail server really does allow ???????????? as an email address."
As for using exception handling for business logic, I agree that is a thing to be avoided. But this is one of those cases where the convenience and clarity may outweigh the dogma.
Besides, if you do anything else with the e-mail address, it's probably going to involve turning it to a MailAddress. Even if you don't use this exact function, you will probably want to use the same pattern. You can also check for specific kinds of failure by catching different exceptions: null, empty, or invalid format.
--- Further reading ---
Documentation for System.Net.Mail.MailAddress
Explanation of what makes up a valid email address
这是一个老问题,但我在 SO 上找到的所有答案,包括最近的答案,都与这个问题类似。但是,在 .Net 4.5 / MVC 4 中,您可以通过添加 System.ComponentModel.DataAnnotations 中的 [EmailAddress] 注释来将电子邮件地址验证添加到表单中,所以我想知道为什么我不能只使用 .Net 中的内置功能。网一般。
这似乎有效,而且在我看来相当优雅:
This is an old question, but all the answers I've found on SO, including more recent ones, are answered similarly to this one. However, in .Net 4.5 / MVC 4 you can add email address validation to a form by adding the [EmailAddress] annotation from System.ComponentModel.DataAnnotations, so I was wondering why I couldn't just use the built-in functionality from .Net in general.
This seems to work, and seems to me to be fairly elegant:
我使用这个单行方法来为我完成工作 -
根据注释,如果
source
(电子邮件地址)为空,这将“失败”。I use this single liner method which does the work for me-
Per the comments, this will "fail" if the
source
(the email address) is null..net 4.5 添加了 System.ComponentModel.DataAnnotations.EmailAddressAttribute
你可以浏览EmailAddressAttribute的来源,这个是它内部使用的正则表达式:
.net 4.5 added System.ComponentModel.DataAnnotations.EmailAddressAttribute
You can browse the EmailAddressAttribute's source, this is the Regex it uses internally:
我从#1 中获取了 Phil 的答案并创建了这个类。
像这样调用它:
bool isValid = Validator.EmailIsValid(emailString);
这是该类:
I took Phil's answer from #1 and created this class.
Call it like this:
bool isValid = Validator.EmailIsValid(emailString);
Here is the class:
就我个人而言,我想说你应该确保其中有一个 @ 符号,可能还有一个 .特点。您可以使用许多正则表达式来实现不同的正确性,但我认为其中大多数都会遗漏有效的电子邮件地址,或者让无效的电子邮件地址通过。如果人们想输入一个假电子邮件地址,他们就会输入一个假电子邮件地址。如果您需要验证电子邮件地址是否合法,并且该人控制该电子邮件地址,那么您需要向他们发送一封带有特殊编码链接的电子邮件,以便他们可以验证它确实是真实地址。
Personally, I would say that you should just make sure there is an @ symbol in there, with possibly a . character. There's many regexes you could use of varying correctness, but I think most of these leave out valid email addresses, or let invalid ones through. If people want to put in a fake email address, they will put in a fake one. If you need to verify that the email address is legit, and that the person is in control of that email address, then you will need to send them an email with a special coded link so they can verify that it indeed is a real address.
简短而准确的代码
Short and accurate code
最优雅的方法是使用.Net 的内置方法。
这些方法:
经过尝试和测试。这些方法在我自己的专业项目中使用过。
内部使用正则表达式,可靠且快速。
由 Microsoft 为 C# 制作。无需重新发明轮子。
返回布尔结果。 True 表示电子邮件有效。
对于 .Net 4.5 及更高版本的用户
将此引用添加到您的项目中:
现在您可以使用以下代码:
使用示例
以下是一些要声明的方法:
...以及在操作中演示它们的代码:
此外,此示例:
;
分隔的电子邮件地址。替代方案,对于 .Net 版本低于 4.5 的用户
对于 .Net 4.5 不可用的情况,我使用以下解决方案:
具体来说,我使用:
The most elegant way is to use .Net's built in methods.
These methods:
Are tried and tested. These methods are used in my own professional projects.
Use regular expressions internally, which are reliable and fast.
Made by Microsoft for C#. There's no need to reinvent the wheel.
Return a bool result. True means the email is valid.
For users of .Net 4.5 and greater
Add this Reference to your project:
Now you can use the following code:
Example of use
Here are some methods to declare:
...and code demonstrating them in action:
In addition, this example:
;
.Alternative, for users of a version of .Net less than 4.5
For situations where .Net 4.5 is not available, I use the following solution:
Specifically, I use:
我认为最好的方法如下:
您可以在通用类中拥有这个静态函数。
I think the best way is as follow:
You can have this static function in a general class.
老实说,在生产代码中,我最好做的就是检查
@
符号。我从来没有能够完全验证电子邮件。你知道我如何判断它是否真的有效吗?如果发出去了。如果没有,那就很糟糕,如果有,生活就很好。这就是我需要知道的一切。
To be honest, in production code, the best I do is check for an
@
symbol.I'm never in a place to be completely validating emails. You know how I see if it was really valid? If it got sent. If it didn't, it's bad, if it did, life's good. That's all I need to know.
我发现这个正则表达式是检查 @ 标记以外的内容和接受奇怪的边缘情况之间的一个很好的权衡:
它至少会让你在 @ 标记周围放置一些东西,并至少放置一个看起来正常的域。
I find this regex to be a good trade off between checking for something more than just the @ mark, and accepting weird edge cases:
It will at least make you put something around the @ mark, and put at least a normal looking domain.
我只是想指出,.NET 文档最近添加了有关电子邮件验证的内容,也利用了正则表达式操作。
可以在那里找到对其实现的全面解释。
https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
为了方便起见,这里是他们的测试结果列表:
I just want to point out, that there has been a recent addition to the .NET documentation regarding email validation, also utilitzing Regex operations.
A thorough explanation to their implementation can be found there.
https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
For convenience, here is a list of their test results:
这是我的答案 - Phil 的解决方案对于像“[email protected]”。不管你信不信,这就是 =)(例如,转到 centurylink)。
Phil 的答案也只适用于 PCRE 标准...所以 C# 会接受它,但 javascript 会崩溃。对于 javascript 来说太复杂了。所以你不能使用Phil的解决方案来验证mvc属性。
这是我的正则表达式。它将与 MVC 验证属性很好地配合使用。
- @ 之前的所有内容都被简化,因此至少 javascript 可以工作。只要交换服务器不给我 5.1.3,我就可以在这里放松验证。
- @ 之后的所有内容都是 Phil 针对单字母域修改的解决方案。
对于建议使用 system.net.mail MailMessage() 的人来说,这太灵活了。当然,C# 会接受电子邮件,但一旦您尝试发送电子邮件,交换服务器就会出现 5.1.3 运行时错误。
Here's my answer -- Phil's solution fails for single letter domains like "[email protected]". Believe it or not, that's used =) (goes to centurylink, for instance).
Phil's answer is also going to work only with PCRE standard... so C# will take it, but javascript is going to bomb. It's too complex for javascript. So you can't use Phil's solution for mvc validation attributes.
Here's my regex. It'll work nicely with MVC validation attributes.
- Everything before the @ is simplified, so that at least javascript will work. I'm okay relaxing validation here as long as exchange server doesn't give me a 5.1.3.
- Everything after the @ is Phil's solution modified for single letter domains.
For people suggesting using system.net.mail MailMessage(), that thing is WAY to flexible. Sure, C# will accept the email, but then exchange server will bomb with 5.1.3 runtime error as soon as you try to send the email.
我总结了截至 2021 年我在这门课上为自己写的所有上述答案:
I summarize all the above answers as of the current year 2021 I wrote for myself this class:
电子邮件地址验证并不像看起来那么容易。实际上理论上不可能仅使用正则表达式来完全验证电子邮件地址。
查看我关于它的博客文章,进行讨论主题和使用 FParsec 的 F# 实现。 [/无耻_插件]
Email address validation is not as easy as it might seem. It's actually theoretically impossible to fully validate an email address using just a regular expression.
Check out my blog post about it for a discussion on the subject and a F# implementation using FParsec. [/shameless_plug]
这里有很多强有力的答案。不过,我建议我们退后一步。 @Cogwheel 回答了问题https://stackoverflow.com/a/1374644/388267。然而,如果许多正在验证的电子邮件地址无效,那么在批量验证场景中,成本可能会很高。我建议我们在进入他的 try-catch 块之前使用一些逻辑。我知道可以使用 RegEx 编写以下代码,但这对于新开发人员来说理解成本可能很高。这是我的两便士价值:
There are a lot of strong answers here. However, I recommend that we take a step back. @Cogwheel answers the question https://stackoverflow.com/a/1374644/388267. Nevertheless, it could be costly in a bulk validation scenario, if many of the email address being validated are invalid. I suggest that we employ a bit of logic before we enter into his try-catch block. I know that the following code could be written using RegEx but that could be costly for new developers to understand. This is my twopence worth:
正如许多答案中提到的,电子邮件地址的域很复杂。在这种情况下,我强烈建议不要使用正则表达式。那些匹配(大多数)案例的内容阅读起来极其复杂,因此维护起来也极其复杂。此外,支持所有案件仍然存在困难,而且速度缓慢。
我认为,微软的
EmailAddress
类在这方面有所帮助,但也并不完美。对于一个开源项目,我几年前尝试过使用定制的EmailParser
。用于 [
EmailAddress
] https://github.com/Qowaiv/Qowaiv/blob/master/src/Qowaiv/EmailAddress.cs)。通过使用这种方法,您不仅可以验证电子邮件地址,还可以清除多种格式的显示名称,摆脱
mailto:
前缀,并根据 IP 规范化域文字 -地址,并将所有内容小写(请注意,本地部分正式区分大小写)。您的解决方案应该支持场景(并且提到的解决方案确实支持):
As mentioned in many answers, the domain of email addresses is complex. I would strongly discourage the use of a regex in this case. Those who match (most) cases are extremely complex to read and therefor to maintain. Furthermore, the still have difficulties supporting all cases, and are slow.
Microsoft's
EmailAddress
class helps a bit in that respect, but is not perfect either, I would argue. For an open source project I gave it try some years ago, by using a customizedEmailParser
.That is used in [
EmailAddress
]https://github.com/Qowaiv/Qowaiv/blob/master/src/Qowaiv/EmailAddress.cs).By using this approach, you're not only to validate email addresses, but also by cleaning out multiple formats of display names, getting rid of the
mailto:
-prefix, and normalizing domain literals based on IP-addresses, and lowercasing everything (note that the local part officially is case sensitive).Scenario's your solution should support (and the mentioned one does):
如果您真的并且我的意思是真的想知道电子邮件地址是否有效......请邮件交换器来证明它,不需要正则表达式。如果需要,我可以提供代码。
一般步骤如下:
1. 电子邮件地址有域名部分吗? (@>0的索引)
2.使用DNS查询询问域是否有邮件交换器
3.打开与邮件交换器的tcp连接
4.使用smtp协议,使用电子邮件地址作为收件人向服务器打开消息
5.解析服务器的响应。
6. 如果您做到了这一步,请退出该消息,一切都很好。
正如您可以想象的那样,非常昂贵的时间并且依赖于 smtp,但它确实有效。
If you really and I mean really want to know if an email address is valid...ask the mail exchanger to prove it, no regex needed. I can provide the code if requested.
General steps are as follows:
1. does email address have a domain name part? (index of @ > 0)
2. using a DNS query ask if domain has a mail exchanger
3. open tcp connection to mail exchanger
4. using the smtp protocol, open a message to the server using the email address as the reciever
5. parse the server's response.
6. quit the message if you made it this far, everything is good.
This is as you can imagine, very expensive time wise and relies on smtp, but it does work.
对@Cogwheel答案进行一点修改
a little modification to @Cogwheel answer
一般来说,验证电子邮件地址的正则表达式并不是一件容易想到的事情;在撰写本文时,电子邮件地址的语法必须遵循相对较高的标准,并且在正则表达式中实现所有这些标准实际上是不可行的!
我强烈建议您尝试我们的 EmailVerify.NET,这是一个成熟的 .NET 库,可以验证电子邮件地址是否符合当前 IETF 标准(RFC 1123、RFC 2821、RFC 2822、RFC 3696、RFC 4291、RFC 5321 和 RFC 5322),测试相关 DNS 记录,检查目标是否符合邮箱可以接受消息,甚至可以判断给定的地址是否是一次性的。
免责声明:我是该组件的首席开发人员。
Generally speaking, a regular expression to validate email addresses is not an easy thing to come up with; at the time of this writing, the syntax of an email address must follow a relatively high number of standards and implementing all of them within a regular expression is practically unfeasible!
I highly suggest you to try our EmailVerify.NET, a mature .NET library which can validate email addresses following all of the current IETF standards (RFC 1123, RFC 2821, RFC 2822, RFC 3696, RFC 4291, RFC 5321 and RFC 5322), tests the related DNS records, checks if the target mailboxes can accept messages and can even tell if a given address is disposable or not.
Disclaimer: I am the lead developer for this component.
一个不使用正则表达式的简单方法(我不喜欢它的可读性差):
示例:
IsValidEmail("@b.com") // false
IsValidEmail("[电子邮件受保护]") // false
IsValidEmail("a @bcom") // false
IsValidEmail("ab@com") // false
IsValidEmail("a@b.") // false
IsValidEmail("a [电子邮件受保护]") // false
IsValidEmail("a@b c.com") // false
IsValidEmail("[电子邮件受保护]") // true
IsValidEmail("[电子邮件受保护]") // true
IsValidEmail("[电子邮件受保护]") // true
IsValidEmail("[email protected]") // true
它应该很简单,因此不处理罕见的情况例如,带方括号的域中包含空格(通常允许)的电子邮件、带有 IPv6 地址的电子邮件等。
A simple one without using Regex (which I don't like for its poor readability):
Examples:
IsValidEmail("@b.com") // false
IsValidEmail("[email protected]") // false
IsValidEmail("a@bcom") // false
IsValidEmail("a.b@com") // false
IsValidEmail("a@b.") // false
IsValidEmail("a [email protected]") // false
IsValidEmail("a@b c.com") // false
IsValidEmail("[email protected]") // true
IsValidEmail("[email protected]") // true
IsValidEmail("[email protected]") // true
IsValidEmail("[email protected]") // true
It is meant to be simple and therefore it doesn't deal with rare cases like emails with bracketed domains that contain spaces (typically allowed), emails with IPv6 addresses, etc.
如果您使用 FluentValidation 您可以编写如下简单的内容:
In case you are using FluentValidation you could write something as simple as this:
来自 @Cogwheel 的投票最多的答案是最佳答案,但是我尝试实现
trim()
字符串方法,因此它将修剪从字符串开始到结束的所有用户空白。检查下面的代码以获取完整示例 -The most voted answer from @Cogwheel is best answer however i have tried to implement
trim()
string method so it will trim all user white space from string start to end. Check the code bellow for full example-另一个正则表达式匹配答案:
Another Regex Match answer :
通过 System.Text.RegularExpressions 检查电子邮件字符串的格式是否正确:
Check email string is right format or wrong format by
System.Text.RegularExpressions
:/使用创建“new EmailAddressAttribute();”时使用的内部正则表达式.Net4.5中的组件>>使用 System.ComponentModel.DataAnnotations;
//验证电子邮件地址......已测试且工作正常。
另外,您可以使用:
http://msdn .microsoft.com/en-us/library/01escwtf(v=vs.110).aspx
/Using the Internal Regex used in creating the "new EmailAddressAttribute();" component in .Net4.5 >>> using System.ComponentModel.DataAnnotations;
//To Validate an Email Address......Tested and Working.
Also, You can use this:
http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx
我将 Poyson 1 的答案简化如下:
I succinctified Poyson 1's answer like so:
识别 emailid 是否有效的简单方法。
Simple way to identify the emailid is valid or not.