用于密码分级的正则表达式

时间:2016-06-01 08:57:47

标签: php regex

我正在研究使用密码质量的正则表达式。这个想法是,如果密码只包含1个大写字符或至少6个大写字符,则认为密码是平庸的。密码本身至少应为8个字符。

期望的行为:

Aaaaaaaa - >匹配

AAAAAAaa - >匹配

AAaaaaaa - >没有比赛

我试过这样的事情:

(?=.*[A-Z]{1,1}|(?=.*[A-Z]{6,})).{8,}

哪个不起作用,因为它也匹配AAaaaaaa。问题是第一个允许2-5个大写字符的正向前瞻,但我无法弄清楚如何避免这种情况。

3 个答案:

答案 0 :(得分:2)

您应该将第一个前瞻限制为只需要整个字符串中的1个大写字母。只需将完整的字符串模式定义为任何非大写字母后跟1个大写字母,然后允许任意数量的非大写字母字符

如果您计划连续使用6个大写字母,请使用

/^(?=[^A-Z]*[A-Z][^A-Z]*$|.*[A-Z]{6,}).{8,}$/
     ^^^^^^^^^^^^^^^^^^^^

请参阅this regex demo

如果这6个大写字母可以分散在字符串周围,请使用

/^(?=[^A-Z]*[A-Z][^A-Z]*$|(?:[^A-Z]*[A-Z]){6,}).{8,}$/
                          ^^^^^^^^^^^^^^^^^^^^ 

其中(?:[^A-Z]*[A-Z]){6,}搜索至少6次出现的0 +非大写字母字符后跟一个大写字母。请参阅this regex demo

如果您需要支持Unicode,请在正则表达式的末尾添加/u修饰符,并将[A-Z]替换为\p{Lu},将[^A-Z]替换为\P{Lu}

此外,建议使用\A代替^\z代替$,因为它是密码验证。

另一个基于bobble bubble建议的逻辑的正则表达式:

^                           # String start
 (?=.{8,}$)                 # 8 or more characters other than a newline
 (?:
   [^A-Z]*[A-Z][^A-Z]* # a string with 1 uppercase letter only
    |                       # or...
   (?:[^A-Z]*[A-Z]){6}      # 6 occ. of 0+ chars other than uppercase letters followed with 1 uppercase letter
   .*                       # 0+ chars other than a newline
 )
$                           # string end

请参阅regex demo和1行:

/^(?=.{8,}$)(?:[^A-Z\n]*[A-Z][^A-Z\n]*|(?:[^A-Z\n]*[A-Z]){6}.*)$/

请参阅this demo

答案 1 :(得分:1)

您的.*[A-Z]也会消耗鞋面。在大写字母之间使用exclusion

^(?=.{8})(?:([^A-Z]*[A-Z]){6}.*|(?1)[^A-Z]*$)

检查是否有至少6个或正好1个上部被非上部包围。

  • (?=.{8})开始时的前瞻检查至少8个字符
  • (?1)是对([^A-Z]*[A-Z])
  • 的引用

更多解释和demo at regex101

答案 2 :(得分:0)

确定。我认为这不是强密码的合适标准,但不管怎么说,让我们对这个问题嗤之以鼻:用字符串计算大写字母。

我认为使用regexp真的不容易。它需要是一个吗?然后,您应该从问题中删除php标记...

PHP解决方案:我只是过滤大写字母并在之后计算它们。

$caps = strlen(preg_replace('/[^A-Z]+/', '', $pass)); // number of uppercase chars in `$pass`

$mediocre = strlen($pass) != 8 || $caps > 5 || $caps < 2;
// mediocre if $pass is not exactly 8 chars long and does not contain between 2 and 5 uppercase characters