密码验证不允许在屏幕末尾显示特殊字符

时间:2016-01-22 08:29:20

标签: java android regex

我已根据以下条件编写了一个正则表达式来验证密码。

  

您的密码长度应为8到20,且必须至少包含2个字母,1个数字和1个特殊字符。空间不允许

我的正则表达式是 -

final String PASSWORD_PATTERN = 
   "^(?=.*[0-9].{1})(?=.*[A-Za-z].{2})(?=.*[@#$%^&+=].{1})(?=\\S+$).{8,}$";

它适用于所有其他情况,除非我在字符串末尾输入任何特殊字符。请有人建议我做错了什么?

2 个答案:

答案 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 articlethis 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 ,则整个匹配失败。所有这些只在字符串开始之后,在第一个符号之前执行一次。