我需要使用以下规则检查密码字符串:
密码必须包含以下四个组中的三个中的至少一个字符:
为了实现这个目标,我做了两次验证。简单的是第一步,检查允许的字符和长度:
^[a-zA-Z0-9!@\#$%&/=?_.,:;\-]{8,16}$
第二个有点复杂,但我可以通过Stackoverflow answer来解决它:
^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!@\#$%&/=?_.,:;\-])|(?=.*[a-z])(?=.*[0-9])(?=.*[!@\#$%&/=?_.,:;\-])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!@\#$%&/=?_.,:;\-])).{8,16}$
我认为这可能是一个明确而简单的2步骤解决方案......但是...... 有没有办法合并两个正则表达式?
我想在Java,JavaScript和Lua上应用该解决方案。
答案 0 :(得分:1)
首先我要强调一点,我不喜欢你的密码政策。为什么禁止使用其他符号或超过16个字符的密码?如果可能的话,请不要包含这些规则。
为了清楚起见,我已经用扩展形式写了这个正则表达式(即忽略了空格):/\A
(?=.{8,16}\z) # Must contain 8-16 characters
(?!.*[^a-zA-Z\d!@#$%&\/=?_.,:;-]) # Must not contain other characters
(?=.*\d) # Must contain a digit
(?=.*[a-z]) # Must contain a lower case character
(?=.*[A-Z]) # Must contain an upper case character
(?=.*[!@#$%&\/=?_.,:;-]) # Must contain a symbol from this list
/x
上述模式解决了强制执行所有四个规则的问题。理论上,你可以将最后4个条件包装成4个"或者#34;小组 - 就像你原来的例子一样。
然而,再次,我不推荐它。如果您在函数内执行一系列单独的检查,那么您的代码将更易读,有用且可维护。 (例如,这意味着您可以显示更多有用的错误消息,而不仅仅是"正则表达式失败!"。
但是既然你问过....这是正则表达式的怪物:
/\A
(?=.{8,16}\z)
(?!.*[^a-zA-Z\d!@#$%&\/=?_.,:;-])
(
(?=.*\d)
(?=.*[a-z])
(?=.*[A-Z])
|
(?=.*\d)
(?=.*[a-z])
(?=.*[!@#$%&\/=?_.,:;-])
|
(?=.*\d)
(?=.*[A-Z])
(?=.*[!@#$%&\/=?_.,:;-])
|
(?=.*[a-z])
(?=.*[A-Z])
(?=.*[!@#$%&\/=?_.,:;-])
)
/x
如果您不想/无法访问/x
修饰符,请删除所有空格。
答案 1 :(得分:0)
整个验证的单个正则表达式的缺点是,正则表达式很难阅读和维护。将正则表达式条件分离为每个条件的单个检查,并且简单检查String的长度将是更合适且更易读的解决方案。在我看来,以下代码对密码的验证与单个正则表达式一样好,但最好是维护和阅读。
public static void main(String[] args) {
System.out.println(isPasswordValid("Ab$123456"));
System.out.println(isPasswordValid("b$11234566"));
System.out.println(isPasswordValid("Ab$1234634634534252"));
System.out.println(isPasswordValid("$112512312512"));
System.out.println(isPasswordValid("A$115 223"));
}
private static boolean isPasswordValid(String password) {
// The password is to short or to long
if(password.length() < 8 || password.length() > 16) {
return false;
}
int matchedConditions = 0;
// Check for invalid characters
if(password.matches(".*[^A-Za-z0-9!@#$%&/=?_.,:;-].*")) {
return false;
}
// is an uppercase letter present, increase matched condition
if(password.matches(".*[A-Z].*")){
++matchedConditions;
}
// is a lowercase letter present, increase matched condition
if(password.matches(".*[a-z].*")){
++matchedConditions;
}
// is a numeric value present, increase matched condition
if(password.matches(".*[0-9].*")){
++matchedConditions;
}
// is a special character present, increase matched condition
if(password.matches(".*[!@#$%&/=?_.,:;-].*")){
++matchedConditions;
}
// Return if at least 3 conditions were met
return matchedConditions >= 3;
}
输出:
true
true
false
false
false