使用正则表达式VB.Net验证电子邮件

12
我正在使用VB.Net进行一个小项目,我从一个文本框中获取输入,并需要验证它是否是一个电子邮件地址。
我找到了这个表达式"^[_a-z0-9-]+(.[_a-z0-9-]+)@[a-z0-9-]+(.[a-z0-9-]+)(.[a-z]{2,4})$",但我找不到任何测试它是否通过的方法。
我想要一些类似这样的代码:
if not txtEmail.text = regexString then
    something happens..
else
    something else happens..
end if

3
这是一个非常好的问题,应该在StackOverflow上记录下来 - 我认为在这里提出这个问题没有任何问题。 - Jeffrey
6个回答

25

使用 System.Text.RegularExpressions.Regex 类:

Function IsEmail(Byval email as string) as boolean
    Static emailExpression As New Regex("^[_a-z0-9-]+(.[a-z0-9-]+)@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,4})$")

    return emailExpression.IsMatch(email)
End Function

理解这篇答案最重要的一点是,这个正则表达式不是我自己写的。有许多看起来正确实际上是错误的方法,而且你可以从几个层次上处理这个问题。例如,你想将其限制在有效的顶级域名范围内吗?如果是这样,你如何考虑到它们现在偶尔添加新的 TLD 呢?正则表达式是否是进行这种检查的最合适地方,或者应该编写独立的代码进行检查?即使是这个答案中的表达式也已经过时,因为它最初是由一个人编写的。

我建议找到一个外部资源,以确保你使用的表达式会随着时间的推移而得到维护。


3
“如果...那么返回真,否则返回假”肯定是历史上十大反模式之一。 :-/ - Konrad Rudolph
1
表达式出现了错误。请访问https://dev59.com/rXRC5IYBdhLWcg3wOeWB。 - bzlm
3
用于匹配电子邮件地址的正则表达式本质上是有缺陷的。你可以生成一种感觉,认为你几乎涵盖了所有情况,但最终几乎总会有一个有效的模式被拒绝,或者一个无效的模式被允许通过。你的正则表达式不将撇号视为有效字符,但实际上它们是有效的。 - Tomalak
3
如果...那么返回True,否则返回False,比“返回Matchobject”更易读。事实上,你所做的就是这个。仅凭外观无法确定返回类型,可能需要看400行代码才能确定返回类型是否为布尔值。易读性胜过你追求最小化代码浪费的“完美模式”。任何时候都是如此。更好的可读性可以减少错误。根据我25年的经验,大多数自认为拥有完美模式的程序员往往会有最多的错误。 - hamish
上面的正则表达式在一个First.Name@Company.com的电子邮件地址上失败了,所以我使用了这个: "^((([!#$%&'+-/=?^_{|}\w])|([!#$%&'*+-/=?^_{|}\w][!#$%&'‌​*+-/=?^_{|}.\w]{0‌​,}[!#$%&'*+-/=?^_{|‌​}\w]))[@]\w+([-.]\w‌​+)*.\w+([-.]\w+))$"。源正则表达式和测试页面在这里:regexlib.com/RETester.aspx?regexp_id=2558。 - Jeff Mergler
显示剩余4条评论

6

我的正则表达式匹配电子邮件地址的文章中选择您最喜欢的正则表达式,并将其插入此Visual Basic代码:

If Regex.IsMatch(SubjectString, "regex") Then
    Error = False
Else
    Error = True
End If

匹配电子邮件地址的最佳正则表达式是一个有争议的话题,我不想在这里深入讨论。我的文章讨论了选择正则表达式时应该注意的问题。Joel Coehoorn答案中的正则表达式绝对不是一个好的选择。


链接网页上有各种权衡的好描述。 - WileCau

5
有一个非常好的网站可以做这种事情,它叫做http://regexlib.com/。它不仅有一个测试应用程序,您可以将正则表达式粘贴到其中进行测试,而且还有一个正则表达式库,您可以使用社区反馈来验证其有效性等。我不是正则表达式大师,所以当我需要快速的正则表达式时就会去这里。
此外,如果您想开发自己的正则表达式,有一个很好的工具叫做Regex Buddy,它允许您使用易于理解的英语解释来创建和测试您的正则表达式。

我曾遇到一个情况,其中一个电子邮件未能通过上述简单的正则表达式"^[a-z0-9-]+(.[a-z0-9-]+)@[a-z0-9-]+(.[a-z0-9-]+)(.[a-z]{2,4})$"。回到这里后,我使用了Anderson很慷慨地分享的regexlib,并搜索了最高评分的“电子邮件”正则表达式。有4个匹配项,这个是列表中排名最高的,对我来说效果最好:"^((([!#$%&'+-/=?^{|}~\w])|([!#$%&'*+\-/=?^_{|}\w][!#$%&'*+-/=?^_`{|}.\w]{0,}[!#$%&'*+-/=?^_`{|}~\w]))[@]\w+([-.]\w+).\w+([-.]\w+))$" 源代码和测试页面在这里:http://regexlib.com/RETester.aspx?regexp_id=2558 - Jeff Mergler

5

可能与正则表达式无关,但您可以使用.NET 2.0的一些内置功能:

try
{
   MailAddress email = new MailAddress(txtEmail.Text);
}
catch(FormatException fe)
{
   // output error
}

1
这个在我目前工作的项目中到处都是,我正在将其删除。我不认为抛出异常是好的逻辑或验证技术,除此之外,它还是一项昂贵的任务。如果有需要,请随时纠正我。 - matt_lethargic
我曾经费了很大的劲才让它崩溃,我传递了各种垃圾邮件给它,但它毫不例外地将它们全部吞噬了。最终我从我的代码中移除了这个功能。 - Jeff Mergler
如果您使用电子邮件地址,例如 john.doe@anywhere.com,并在 john. 之后输入空格,则 MailAddress 对象将接受该文本,并且 MailAddress.Address 将具有值 doe@anywhere.com,而不会抛出异常。 - HardCode

2

这个正则表达式并不完整...实际上...大多数都不是(查看这篇文章这篇文章)。

除非你真的喜欢痛苦,否则使用正则表达式来验证电子邮件地址并不是正确的方法。


1
你能告诉大家在 .net 中验证电子邮件地址的正确方法是什么吗? - Antonio Leite

-2

电子邮件地址:RFC 2822(简化版) 匹配普通电子邮件地址。不检查顶级域。 需要打开“不区分大小写”选项。

Dim FoundMatch As Boolean
Try
    FoundMatch = Regex.IsMatch(txtEmail.text, "\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", RegexOptions.IgnoreCase)
Catch ex As ArgumentException
    'Syntax error in the regular expression
End Try

If Not FoundMatch Then
   Error = True
Else
   Error = False
End If

表达式出现错误(例如,不允许仅使用顶级域名地址)。请参见https://dev59.com/rXRC5IYBdhLWcg3wOeWB。 - bzlm
示例没有问题。它没有检查顶级域名。正如我在评论中提到的那样,请参阅我的另一个评论以获取一个检查顶级域名的示例。 - Mick
3
我永远不会理解为什么有人会写像你在这段代码片段中最后一个 IF 语句那样的东西。那太荒谬了。它应该是:Error = Not FoundMatch。 - Josh Stodola
是的,那会更简洁。我当时是为了通用性而写的。现在你知道为什么有人会像这段代码片段中的最后一个IF语句那样编写了 :-) - Mick

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