好的正则表达式书呆子! 我使用正则表达式前瞻断言进行密码验证,类似于此处描述的模式:
\A(?=\w{6,10}\z)(?=[^a-z]*[a-z])(?=(?:[^A-Z]*[A-Z]){3})(?=\D*\d)
但是,我们只想要求4个断言中的任何3个有效 - 不一定都是有效的。有关如何做到这一点的任何想法?
答案 0 :(得分:2)
要缩短任何类型的模式,请分解:
\A(?:
(?=\w{6,10}\z) (?=.*[a-z]) (?: (?:.*[A-Z]){3} | .*\d )
|
(?=.*\d) (?=(?:.*[A-Z]){3}) (?: .*[a-z] | \w{6,10}\z )
)
请注意,您不需要前瞻来测试最后一个条件。
其他方式,每个条件都是可选的,并使用命名组进行计数(仅限.net):
\A
(?<c>(?=\w{6,10}\z))?
(?<c>(?=[^a-z]*[a-z]))?
(?<c>(?=(?:[^A-Z]*[A-Z]){3}))?
(?<c>(?=\D*\d))?
(?<-c>){3} # decrement c 3 times
(?(c)|(?!$)) # conditional: force the pattern to fail if too few conditions succeed.
答案 1 :(得分:1)
在单个正则表达式中没有“简单”的方法。唯一的方法是定义“四分之三”断言的所有可能的排列 - 例如
\A(?=\w{6,10}\z)(?=[^a-z]*[a-z])(?=(?:[^A-Z]*[A-Z]){3})| # Maybe no digit
\A(?=[^a-z]*[a-z])(?=(?:[^A-Z]*[A-Z]){3})(?=\D*\d)| # Maybe wrong length
\A(?=\w{6,10}\z)(?=(?:[^A-Z]*[A-Z]){3})(?=\D*\d)| # Maybe no lower
\A(?=\w{6,10}\z)(?=[^a-z]*[a-z])(?=\D*\d) # Maybe not enough uppers
然而,这种精神崩溃的正则表达式显然不是一个好的解决方案。
更好的方法是执行四个检查单独(使用正则表达式或其他方式),并计算至少有三个通过的条件。
...但是,让我们回到这里,然后问:为什么你这样做?您正在实施密码熵检查。根据您的模糊规则,以下密码有效:
以下密码无效:
我强烈建议不要采取这种奇怪的限制性政策。
答案 2 :(得分:1)
最简单的方法是使用单独的正则表达式,并检查其中3/4是否在您的代码语言中成功。在正则表达式中执行此操作的唯一方法是呈现所有情况。话虽这么说,这可能是最容易呈现所有选项的方法(在正则表达式中),因为它允许您在一个位置(定义它们的位置)编辑模式而不是多次(更容易出错)。很少支持正则表达式中的DEFINE
构造,但PCRE正则表达式支持。
您还可以让代码生成每个正则表达式排列。见this question about generating all permutations of a list in python
我不知道你为什么要为密码做这件事,它被认为是弊端,但是,既然你要求它,我想我会给你是regex中最简单的解决方案......你真的应该只检查最小长度(如果你想[基于算法]向用户显示你的系统如何安全找到他们的密码那么复杂)。 子>
(?(DEFINE)
(?<w>(?=\w{6,10}\z))
(?<l>(?=[^a-z]*[a-z]))
(?<u>(?=(?:[^A-Z]*[A-Z]){3}))
(?<d>(?=\D*\d))
)
\A(?:
(?&w)(?&l)(?&u)|
(?&w)(?&l)(?&d)|
(?&w)(?&u)(?&d)|
(?&l)(?&u)(?&d)
)
注意:上面的正则表达式使用x
修饰符(忽略空格),以便我们可以很好地组织内容。