gpt4 book ai didi

asp.net - 使用ASP.NET 3.5验证的电子邮件格式验证的最佳正则表达式

转载 作者:行者123 更新时间:2023-12-04 09:13:04 25 4
gpt4 key购买 nike

我已经使用以下两个正则表达式使用ASP.NET验证控件来测试有效的电子邮件表达式。我想知道从性能的角度来看哪个更好,或者有人是否有更好的表达。

 - \w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* - ^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$

I'm trying avoid the "exponentially slow expression" problem described on the BCL Team Blog.

UPDATE

Based on feedback I ended up creating a function to test if an email is valid:

Public Function IsValidEmail(ByVal emailString As String, Optional ByVal isRequired As Boolean = False) As Boolean
Dim emailSplit As String()
Dim isValid As Boolean = True
Dim localPart As String = String.Empty
Dim domainPart As String = String.Empty
Dim domainSplit As String()
Dim tld As String

If emailString.Length >= 80 Then
isValid = False
ElseIf emailString.Length > 0 And emailString.Length < 6 Then
'Email is too short
isValid = False
ElseIf emailString.Length > 0 Then
'Email is optional, only test value if provided
emailSplit = emailString.Split(CChar("@"))

If emailSplit.Count <> 2 Then
'Only 1 @ should exist
isValid = False
Else
localPart = emailSplit(0)
domainPart = emailSplit(1)
End If

If isValid = False OrElse domainPart.Contains(".") = False Then
'Needs at least 1 period after @
isValid = False
Else
'Test Local-Part Length and Characters
If localPart.Length > 64 OrElse ValidateString(localPart, ValidateTests.EmailLocalPartSafeChars) = False OrElse _
localPart.StartsWith(".") OrElse localPart.EndsWith(".") OrElse localPart.Contains("..") Then
isValid = False
End If

'Validate Domain Name Portion of email address
If isValid = False OrElse _
ValidateString(domainPart, ValidateTests.HostNameChars) = False OrElse _
domainPart.StartsWith("-") OrElse domainPart.StartsWith(".") OrElse domainPart.Contains("..") Then
isValid = False
Else
domainSplit = domainPart.Split(CChar("."))
tld = domainSplit(UBound(domainSplit))

' Top Level Domains must be at least two characters
If tld.Length < 2 Then
isValid = False
End If
End If
End If
Else
'If no value is passed review if required
If isRequired = True Then
isValid = False
Else
isValid = True
End If
End If

Return isValid
End Function
笔记:

与RFC相比,
  • IsValidEmail对允许使用的字符的限制更严格,但它不会测试这些字符的所有可能的无效使用情况
  • 最佳答案

    如果您想知道为什么这个问题产生的事件很少,那是因为在开始考虑性能之前,还有许多其他问题需要处理。其中最重要的一点是您是否应该使用正则表达式来验证电子邮件地址,并且共识是您不应该使用正则表达式来验证电子邮件地址。它比大多数人期望的要复杂得多,而且可能毫无意义。

    另一个问题是您的两个正则表达式在它们可以匹配的字符串类型上差异很大。例如,第二个 anchor 定在两端,但第一个不 anchor 定。它会匹配“>>>>foo@bar.com<<<<”,因为其中有些内容看起来像是嵌入了电子邮件地址。也许框架强制正则表达式匹配整个字符串,但是如果是这样,为什么第二个 anchor 定呢?

    另一个区别是,第一个正则表达式在整个地方都使用\w,而第二个在很多地方都使用[0-9a-zA-Z]。在大多数正则表达式中,\w除了字母和数字外还与下划线匹配,但是在某些(包括.NET)中,它也与Unicode已知的每个书写系统中的字母和数字匹配。

    还有许多其他差异,但这是学术上的差异。这些正则表达式都不是很好。请参阅here,以很好地讨论该主题,并提供更好的正则表达式。

    回到最初的问题,我没有看到这两个正则表达式的性能问题。除了该BCL博客条目中引用的嵌套量词反模式之外,您还应该注意正则表达式的两个或多个相邻部分可以匹配同一字符集的情况-例如,

    ([A-Za-z]+|\w+)@

    您发布的任何一个正则表达式都没有类似的内容。由量词控制的部分总是被未量化的其他部分分解。这两个正则表达式都会遇到一些可以避免的回溯,但是有很多比性能更好的理由拒绝它们。

    编辑:因此,第二个正则表达式会遭受灾难性的回溯;在吐口水之前,我应该已经对其进行了彻底的测试。仔细研究一下该正则表达式,我不明白为什么在第一部分中需要外部星号:
    [0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*

    所有要做的就是确保第一个和最后一个字符为字母数字,同时在两者之间允许一些其他字符。这个版本做同样的事情,但是当不可能匹配时,它会更快地失败:
    [0-9a-zA-Z][-.\w]*[0-9a-zA-Z]

    这可能足以消除回溯问题,但是您也可以通过使用原子组来使“@”之后的部分更有效:
    (?>(?:[0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+)[a-zA-Z]{2,9}

    换句话说,如果您已将所有子串都匹配了,这些子串看起来像是带有尾点的域组件,而下一部分看起来却不像TLD,请不要打扰回溯。您必须放弃的第一个字符是最后一个点,并且您知道 [a-zA-Z]{2,9}与之不符。

    关于asp.net - 使用ASP.NET 3.5验证的电子邮件格式验证的最佳正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/936870/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com