我已根据以下条件编写了一个正则表达式来验证密码。
您的密码长度应为8到20,且必须至少包含2个字母,1个数字和1个特殊字符。空间不允许
我的正则表达式是 -
final String PASSWORD_PATTERN =
"^(?=.*[0-9].{1})(?=.*[A-Za-z].{2})(?=.*[@#$%^&+=].{1})(?=\\S+$).{8,}$";
它适用于所有其他情况,除非我在字符串末尾输入任何特殊字符。请有人建议我做错了什么?
答案 0 :(得分:2)
如果不喜欢使用正则表达式,可以编写一个函数来迭代字符串并计算数字,字母或特殊字符的数量。
boolean isValidPassword(char[] pass) {
int letters = 0, digits = 0, specialChars = 0;
if (pass.length < 8 || pass.length > 20) {
return false;
}
for (int i = 0; i < pass.length; i++) {
char ch = pass[i];
if (Character.isLetter(ch)) {
letters++;
}
else if (Character.isDigit(ch)) {
digits++;
}
else if (isSpecialChar(ch)) {
specialChars++;
}
else if (Character.isWhiteSpace(ch)) {
return false;
}
}
return !(letters < 2 || digits < 1 || specialChars < 1);
}
static boolean isSpecialChar(char c) {
switch (c) {
case '@':
case '#':
case '$':
case '%':
case '^':
case '&':
case '+':
case '=':
return true;
default:
return false;
}
}
请注意,this article和this question所述,使用String
时也解决了安全问题。
答案 1 :(得分:0)
该模式不符合您的规范,因为应用了量词{1}
,{2}
。而不是正确的模式。此外,最后一个量词{8,}
允许从8开始的任意数量的字符,但您需要将其数量限制为20.此外,请注意{1}
完全是多余的。此外,我建议在前瞻中使用principle of contrast(查看Lookahead Example: Simple Password Validation)。
您可以使用
final String PASSWORD_PATTERN =
"^(?=[^0-9]*[0-9])(?=(?:[^A-Za-z]*[A-Za-z]){2})(?=[^@#$%^&+=]*[@#$%^&+=])\\S{8,20}$";
请参阅regex demo
解释:
^
- 字符串开始(?=[^0-9]*[0-9])
- 必须至少有一位数字(在可选的非数字之后)(?=(?:[^A-Za-z]*[A-Za-z]){2})
- 应该有2个ASCII字母(使用\pL
匹配Unicode字母,使用其对应的\PL
来匹配Unicode字母以外的字符)(?=[^@#$%^&+=]*[@#$%^&+=])
- 集合中必须至少有一个特殊符号\\S{8,20}
- 8到20个非空白符号$
- 字符串结尾如果任何前瞻返回 false ,则整个匹配失败。所有这些只在字符串开始之后,在第一个符号之前执行一次。