9

我正在尝试创建一个正则表达式以进行模式匹配(用于密码),其中字符串必须介于 8 到 30 个字符之间,必须至少有 2 个数字,至少 2 个字母(不区分大小写),至少 1 个特殊字符,并且没有空间。

我已经让空格和特殊字符匹配工作了,但是因为它们不需要是连续的,所以我被抛出了 2 个数字和 2 个字母。

即它应该匹配a1b2c$ or ab12$or 1aab2c$

像这样的字母?

(?=.*[a-zA-Z].*[a-zA-Z])  // Not sure.

下面的这个字符串有效,但只有当 2 个字母是连续的并且 2 个数字是连续的..如果字母、数字、特殊字符交织在一起,它就会失败。

(?=^.{8,30}$)((?=.*\\d)(?=.*[A-Za-z]{2})(?=.*[0-9]{2})(?=.*[!@#$%^&*?]{1})(?!.*[\\s]))^.* 
4

4 回答 4

9

如果您不希望字母必须连续(?=.*[a-zA-Z].*[a-zA-Z])是正确的方法。同样适用于数字(?=.*\\d.*\\d)(?=(.*\\d){2})

试试这个正则表达式

(?=^.{8,30}$)(?=(.*\\d){2})(?=(.*[A-Za-z]){2})(?=.*[!@#$%^&*?])(?!.*[\\s])^.*
于 2013-03-13T19:03:39.643 回答
5

你的猜测会非常准确。使用括号可以使它看起来更优雅。

(?=(.*[a-zA-Z]){2})

听起来你在正确的轨道上。

于 2013-03-13T19:01:00.263 回答
3

使用循环遍历字符串:

/**
 * Checks to see if the specified string has between 8 and 30 characters, has at least 2 digits, at least 2 letters, at least one special character, and no spaces.
 * @param s the String to be checked
 * @return s, if it passes the above test
 * @throws IllegalArgumentException if it does not
 */
public static String check(String s)
{
    IllegalArgumentException invalid = new IllegalArgumentException();
    if(s.length() < 8 || s.length() > 30)
        throw invalid;
    int letters = 0, numbers = 0, specialChars = 0;
    for(char c : s.toCharArray())
    {
        if(c == ' ')
            throw invalid;
        else if(Character.isLetter(c))
            ++letters;
        else if(Character.isDigit(c))
            ++numbers;
        else
            ++specialChars;

    }
    if(letters < 2 || numbers < 2 || specialChars < 1)
        throw invalid;
    return s;
}
于 2013-03-13T19:04:28.860 回答
0

我观察到您提供的示例不是 8 到 30 个字符

如果您想要 8-30 个字符,请尝试此模式一次

 (?=[^\s]*[^\sa-zA-Z0-9][^\s]*)(?=[^\s]*[a-zA-Z][^\s]*[A-Za-z][^\s]*)(?=[^\s]*\d[^\s]*\d[^\s]*)[^\s]{8,30}
于 2013-03-13T18:58:17.580 回答