在密码策略中,有4个要求。 它应包含以下任何三个
以下正则表达式将匹配所有情况
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{4,8}$
我知道我可以使用' |'然而,声明所有组合将产生一个超长的正则表达式。替换' |'的最佳方式是什么?这样它可以检查输入是否包含组合中的三个条件中的任何一个?
答案 0 :(得分:3)
如果您正在使用PCRE风格,则以下内容可以满足您的需求(为便于阅读而格式化):
^(?:
((?=.*\d))((?=.*[a-z]))((?=.*[A-Z]))((?=.*[^a-zA-Z0-9]))|
(?1) (?2) (?3) |
(?1) (?2) (?4) |
(?1) (?3) (?4) |
(?2) (?3) (?4)
).{4,8}$
一衬里:
^(?:((?=.*\d))((?=.*[a-z]))((?=.*[A-Z]))((?=.*[^a-zA-Z0-9]))|(?1)(?2)(?3)|(?1)(?2)(?4)|(?1)(?3)(?4)|(?2)(?3)(?4)).{4,8}$
Debuggex上的演示
JavaScript regex flavor不支持递归(实际上它不支持很多东西)。更好地使用4种不同的正则表达式,例如:
var validate = function(input) {
var regexes = [
"[A-Z]",
"[a-z]",
"[0-9]",
"[^a-zA-Z0-9]"
];
var count = 0;
for (var i = 0, n = regexes.length; i < n; i++) {
if (input.match(regexes[i])) {
count++;
}
}
return count >=3 && input.match("^.{4,8}$");
};
答案 1 :(得分:1)
当然,这是一种方法,它使用相同的正则表达式的略微修改,但需要一小段代码创作。
^(?=(\D*\d)|)(?=([^a-z]*[a-z])|)(?=([^A-Z]*[A-Z])|)(?=([a-zA-Z0-9]*[^a-zA-Z0-9])|).{4,8}$
这里有五个捕获组 - 检查其中至少有三个是否为空。捕获的空组有效地表示前瞻中的替代方案已匹配,并且左侧的捕获组无法匹配。
例如,在PHP中:
preg_match("/^(?=(\\D*\\d)|)(?=([^a-z]*[a-z])|)(?=([^A-Z]*[A-Z])|)(?=([a-zA-Z0-9]*[^a-zA-Z0-9])|).{4,8}$/", $str, $matches);
$count = -1; // Because the zero-eth element is never null.
foreach ($matches as $element) {
if ( !empty($element)) {
$count += 1;
}
}
if ($count >= 3) {
// ...
}
或Java:
Matcher matcher = Pattern.compile(...).matcher(string);
int count = 0;
if (matcher.matches())
for (int i = 1; i < 5; i++)
if (null != matcher.group(i))
count++;
if (count >= 3)
// ...