【问题标题】:Email RegEx is stuck in an infinite loop when email address does not have an @ symbol当电子邮件地址没有 @ 符号时,电子邮件 RegEx 陷入无限循环
【发布时间】:2018-08-23 00:58:11
【问题描述】:

我有一个适用于除一种情况之外的所有情况的正则表达式,但我无法弄清楚为什么它在这种情况下不起作用,因为逻辑告诉我它应该。

RegEx 用于检查电子邮件地址是否为有效的电子邮件地址。 (注意:我熟悉可接受的电子邮件地址标准,但我不是在寻找符合这些标准的正则表达式,我的雇主对有效电子邮件地址有自己的规则)

你能告诉我我的 RegEx 出了什么问题,所以它可以与我必须使用的有效电子邮件地址规则一起工作吗? (见下文规则)

我的正则表达式是:

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

构建此 RegEx 时我必须遵循并一直使用的规则是:

  • 有效字符包括所有英文字母 (a-z)、所有数字 (0-9)、短划线 (-)、下划线 (_)、句点 (.) 和加号 (+)。
  • 电子邮件地址的第一个字符可以是下划线(即:_peter@test.com)
  • 一个破折号可以在一段时间后存在(即:peter.-@test.com)
  • 在@符号之前不能存在句点(即:peter.@test.com)
  • 域不能以破折号开头(即:peter@-test.com)
  • 子域不能以破折号开头(即:peter@test.-com)
  • 域或子域不能是破折号(即:peter@--.com)(即:peter@test.--)

我一直在使用此 VB.NET 代码测试电子邮件地址:

Public Const EMAIL_VALIDATE_REGEX As String = "^([\+\-_\.0-9a-zA-Z]([\+\-_\.0-9a-zA-Z]+)*)+@(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]*\.)+[a-zA-Z0-9]{2,17})$"

Public Function IsEmailAddressValid(ByVal sCheckEmailAddress As String) As Boolean
    Try
        sCheckEmailAddress = Trim$(sCheckEmailAddress)
        Return Regex.IsMatch(sCheckEmailAddress, EMAIL_VALIDATE_REGEX)
    Catch Exp As Exception
        Return False
    End Try
End Function

上述正则表达式适用于所有规则,并为除此电子邮件地址之外的所有电子邮件地址返回正确的 True 或 False:

peter.peter.canada.ca

如果我在这个无效的电子邮件地址上使用我的 RegEx(它缺少一个 @ 符号!),我的代码就会挂起。我相信我的 RegEx 中有一个无限循环。

感谢您提供的任何帮助,以找出我的 RegEx 公式有什么问题会导致它陷入循环。

【问题讨论】:

    标签: .net regex vb.net email


    【解决方案1】:

    这就是问题所在

     (                             # (1 start)
            [\+\-_\.0-9a-zA-Z]
          ( [\+\-_\.0-9a-zA-Z]+ )*      # (2)
     )+                            # (1 end)
    

    您可以看到这两个类是相同的,并且都嵌入其中
    嵌套量词。

    改成

     (                             # (1 start)
         [\+\-_\.0-9a-zA-Z]+
     )                            # (1 end)
    

    你可以走了。

    注意 - 为了最大限度地提高效率,您的正则表达式会考虑到这一点

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

     ^ 
     (                                 # (1 start)
          [+\-_.0-9a-zA-Z]+ 
     )                                 # (1 end)
     @
     (                                 # (2 start)
          ( [0-9a-zA-Z] [-\w]* \. )+        # (3)
          [a-zA-Z0-9]{2,17} 
     )                                 # (2 end)
     $
    

    附录 1

    •A period CANNOT exist immediately before the @ symbol

    在这种情况下,如果句点被非句点包围,则只需使句点有效。

    ^([-+_0-9a-zA-Z]+(?:\.?[-+_0-9a-zA-Z])*)@((?:[0-9a-zA-Z][-\w]*\.)+[a-zA-Z0-9]{2,17})$

     ^ 
     (                             # (1 start)
          [-+_0-9a-zA-Z]+ 
          (?:
               \.?
               [-+_0-9a-zA-Z] 
          )*
     )                             # (1 end)
     @
     (                             # (2 start)
          (?: [0-9a-zA-Z] [-\w]* \. )+
          [a-zA-Z0-9]{2,17} 
     )                             # (2 end)
     $ 
    

    【讨论】:

    • 这有效并停止了无限循环。所以我猜第二个嵌套量词是导致循环的原因。 RegEx 似乎没有捕捉到你不能有“.@”的情况,例如,“peter.@test.com”
    • @ThePeter - 为期间添加了附录 1。还有其他变化吗?
    • 如果您希望句号在开始时有效(但仍不能在 @ 之前),请告诉我,我会进行调整。
    • 第一个字符应该是句号,所以是的,我很想看到它再次调整!
    • 效果很好。我已经针对 20 多种电子邮件变体对其进行了测试,并且效果很好。
    猜你喜欢
    • 2015-01-23
    • 1970-01-01
    • 2011-09-24
    • 2012-04-08
    • 2018-02-08
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多