【问题标题】:Regular Expression - Password Validation is not working正则表达式 - 密码验证不起作用
【发布时间】:2011-03-01 18:28:11
【问题描述】:

我必须使用正则表达式验证密码。 密码规则是至少 1 个大写字母和至少 2 个数字。

它工作正常,除非字符出现在字符串的末尾。

我使用的正则表达式是

"^(?=.*\d.{2})(?=.*[A-Z].{1})(?=.*[@#$%^&+=].{2}).{8,12}$"

规则:

  • 最小长度 = 8
  • 最小大写 = 1
  • 最小数字 = 2
  • 最小特殊字符 = 1

它适用于Test123$$Test$123TEST123$sTest123$1Test12$3,但如果指定的字符出现在字符串的末尾,如Test123$Test$a12、@987654329,它会失败@, 123aa@@T.

如果有任何解决方法,请告诉我。

【问题讨论】:

  • 您的正则表达式仅适用于Test$123
  • 如果您尝试 123$$Test 会发生什么?我怀疑它会失败。我不太确定使用正则表达式是否是实现此目的的最佳工具。
  • @whatsisname 在这种情况下它不是最好的,但它会起作用。检查我的正则表达式:您的字符串成功通过。

标签: regex validation


【解决方案1】:

在您的正则表达式中,我发现了一些问题:

  • (?=.*\d.{2}) - 为什么第二个 .,你不能用 {2} 检查两次出现,因为假设它们在附近...... Test1$2$3 也应该被允许。 ..
  • (?=.*[A-Z].{1}) - 为什么是第二个 .
  • (?=.*[@#$%^&+=].{2}) - 再说一遍,为什么第二个 .,你为什么要检查 2 次出现?规范说一个特殊的字符。
  • (您最多检查 12 个字符,还有哪些未指定)

试试

"^(?=.*\d.*\d)(?=.*[A-Z])(?=.*[@#$%^&+=]).{8,12}$"

通过:

Debug.Assert( regex.IsMatch( "Test123$" ) );
Debug.Assert( regex.IsMatch( "Test123$$" ) );
Debug.Assert( regex.IsMatch( "$Test1$2" ) );   // two numbers, not following
Debug.Assert( regex.IsMatch( "Test$123" ) );
Debug.Assert( !regex.IsMatch( "Test12$" ) );   // 7 chars
Debug.Assert( !regex.IsMatch( "Test12345" ) ); // no special char
Debug.Assert( !regex.IsMatch( "Test$$$$" ) );  // no number
Debug.Assert( !regex.IsMatch( "Test$3$$" ) );  // only one number
Debug.Assert( !regex.IsMatch( "test12$$" ) );  // no upper case

【讨论】:

  • 你为什么使用{1}量词?
  • @SilentGhost - 正是我要问的。
  • @SilentGhost,@GalacticCowboy:所有愚蠢的来源:复制和粘贴 :) 我修改了原来的正则表达式...将编辑,谢谢提示。
【解决方案2】:

您的问题是您使用(atom).{length} 并且长度应用于.,而不是atom。你应该使用(atom){length}。其次,\d{2} 不是«最小数字:2»。它是«2 个后续数字»。 «Minimum numeric: 2» 看起来像这样:.*\d.*\d,所以完整的正则表达式(注意 (atom){1}(atom) 是相同的正则表达式):

^(?=.*\d.*\d)(?=.*[A-Z])(?=.*[@#$%\^&+=]).{8,12}$

并且,请将{8,12} 替换为{8,}:您不应禁止用户输入长密码。

【讨论】:

  • 除非“长”意味着它会导致其他问题。但是,是的,没有理由不允许使用 20-30 个字符的密码。如果您正确地对密码进行加盐/散列处理,那么长度无论如何都不是问题。
【解决方案3】:

您的要求列表未指定常规语言。因此,使用正则表达式进行匹配会很困难(如果不是不可能的话)。

【讨论】:

    【解决方案4】:

    虽然您没有说明您使用的是哪种正则表达式,但我建议采用以下方法,如果不是最有效的话,这种方法更具可读性和可维护性(仅使用 Python):

    >>> import string
    >>> def valid(s):
        return 8 <= len(s) <= 12 and \
               any(c in string.ascii_uppercase for c in s) and \
               sum(c in string.digits for c in s) >= 2 and \
               any(c in string.punctuation for c in s)
    
    >>> valid('abcdefA')
    False
    >>> valid('123aa@@T')
    True
    >>> valid('Test123$')
    True
    >>> valid('Test123_')
    True
    

    【讨论】:

      【解决方案5】:

      您无法为此创建有限状态机,因此(除非在实践中正则表达式与理论上有所不同)您将无法为此找到正则表达式。

      主要是因为它涉及计数,这需要有限状态机所没有的“内存”。

      编辑:显然,DFA“技术”取得了进步。请参阅此帖子的 cmets。

      【讨论】:

      • 许多正则表达式支持“回溯”和“零宽度断言”的概念,这正是 OP 想要的。 FSA 更复杂,但并非不可能。
      猜你喜欢
      • 2012-11-03
      • 2015-11-30
      • 1970-01-01
      • 2015-03-27
      • 2011-05-06
      • 2016-10-19
      • 2011-03-24
      相关资源
      最近更新 更多