我正在研究使用密码质量的正则表达式。这个想法是,如果密码只包含1个大写字符或至少6个大写字符,则认为密码是平庸的。密码本身至少应为8个字符。
期望的行为:
Aaaaaaaa - >匹配
AAAAAAaa - >匹配
AAaaaaaa - >没有比赛
我试过这样的事情:
(?=.*[A-Z]{1,1}|(?=.*[A-Z]{6,})).{8,}
哪个不起作用,因为它也匹配AAaaaaaa。问题是第一个允许2-5个大写字符的正向前瞻,但我无法弄清楚如何避免这种情况。
答案 0 :(得分:2)
您应该将第一个前瞻限制为只需要整个字符串中的1个大写字母。只需将完整的字符串模式定义为任何非大写字母后跟1个大写字母,然后允许任意数量的非大写字母字符。
如果您计划连续使用6个大写字母,请使用
/^(?=[^A-Z]*[A-Z][^A-Z]*$|.*[A-Z]{6,}).{8,}$/
^^^^^^^^^^^^^^^^^^^^
如果这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