密码的Java-Regex

密码的Java-Regex,java,regex,Java,Regex,我如何构造一个正则表达式,使我正在创建的密码字段包含至少一个数字、至少一个小写字母和至少一个大写字母,其中顺序无关紧要,并且这些字符之间可以有任何内容 我尝试过这个方法,得到了类似的结果:.*\\d.[a-z].[a-z]* 但这要求数字排在第一位,小写字母排在第二位,大写字母排在最后。正则表达式不适合这样复杂的场景。在正则表达式中实现它的唯一方法是列出所有可能性: (abc|acb|bac|bca|cab|cba) 其中a、b和c是表示您个人需求的子模式,例如abc将是。*\\d.[a-z]

我如何构造一个正则表达式,使我正在创建的密码字段包含至少一个数字、至少一个小写字母和至少一个大写字母,其中顺序无关紧要,并且这些字符之间可以有任何内容

我尝试过这个方法,得到了类似的结果:.*\\d.[a-z].[a-z]*
但这要求数字排在第一位,小写字母排在第二位,大写字母排在最后。

正则表达式不适合这样复杂的场景。在正则表达式中实现它的唯一方法是列出所有可能性:

(abc|acb|bac|bca|cab|cba)
其中a、b和c是表示您个人需求的子模式,例如abc将是。*\\d.[a-z].[a-z].*,bac代表[a-z].....*\\d.[a-z].*等等。祝您好运维护这样一个怪物。我的技巧是为每个部分创建java常量:

private static final String DI = "\\d+";
private static final String LO = "[a-z]+";
private static final String UP = "[A-Z]+";
private static final String WI = ".*";
private static final String OR = "|";
private static final Pattern REGEX = Pattern .compile(
    WI + DI + WI + LO + WI + UP + WI + OR
  + WI + LO + WI + DI + WI + UP + WI + OR
  // etc
);

正则表达式不适合这样复杂的场景。在正则表达式中实现它的唯一方法是列出所有可能性:

(abc|acb|bac|bca|cab|cba)
其中a、b和c是表示您个人需求的子模式,例如abc将是。*\\d.[a-z].[a-z].*,bac代表[a-z].....*\\d.[a-z].*等等。祝您好运维护这样一个怪物。我的技巧是为每个部分创建java常量:

private static final String DI = "\\d+";
private static final String LO = "[a-z]+";
private static final String UP = "[A-Z]+";
private static final String WI = ".*";
private static final String OR = "|";
private static final Pattern REGEX = Pattern .compile(
    WI + DI + WI + LO + WI + UP + WI + OR
  + WI + LO + WI + DI + WI + UP + WI + OR
  // etc
);

实现这一目标的一种方法是

1首先通过使用 单独的regex,比如regex-1

2接下来使用另一个正则表达式检查它是否包含数字

3检查是否有其他规则


打破规则可以解决您面临的问题,还可以改进您报告错误的方式。

实现这一点的一种方法是

1首先通过使用 单独的regex,比如regex-1

2接下来使用另一个正则表达式检查它是否包含数字

3检查是否有其他规则


打破规则可以解决您面临的问题,也可以改进您报告错误的方式。

您的不是正则表达式特别擅长的用例之一–如果您一直使用正则表达式,我想您别无选择,只能列举以下6种情况:

.*[0-9].*[a-z].*[A-Z].*|.*[0-9].*[A-Z].*[a-z].*|.*[a-z] ... | ...
使用实际的java代码进行检查将更容易且更可读:

String  password = "";
boolean complies = password.matches(".*[0-9].*")
                && password.matches(".*[a-z].*")
                && password.matches(".*[A-Z].*");
或者更丑陋,但可能更快:

boolean complies = false;
{
    boolean hasDigit     = false;
    boolean hasLowercase = false;
    boolean hasUppercase = false;
    for (int i = 0; i < password.length(); i++) {
        char c = password.charAt(i);
        hasDigit     |= '0' <= c && c <= '9';
        hasLowercase |= 'a' <= c && c <= 'z';
        hasUppercase |= 'A' <= c && c <= 'Z';
        if (hasDigit && hasLowercase && hasUppercase) {
            complies = true;
            break;
        }
    }
}

您的不是正则表达式特别擅长的用例之一–如果您一直使用正则表达式,我想您别无选择,只能列举以下6种情况:

.*[0-9].*[a-z].*[A-Z].*|.*[0-9].*[A-Z].*[a-z].*|.*[a-z] ... | ...
使用实际的java代码进行检查将更容易且更可读:

String  password = "";
boolean complies = password.matches(".*[0-9].*")
                && password.matches(".*[a-z].*")
                && password.matches(".*[A-Z].*");
或者更丑陋,但可能更快:

boolean complies = false;
{
    boolean hasDigit     = false;
    boolean hasLowercase = false;
    boolean hasUppercase = false;
    for (int i = 0; i < password.length(); i++) {
        char c = password.charAt(i);
        hasDigit     |= '0' <= c && c <= '9';
        hasLowercase |= 'a' <= c && c <= 'z';
        hasUppercase |= 'A' <= c && c <= 'Z';
        if (hasDigit && hasLowercase && hasUppercase) {
            complies = true;
            break;
        }
    }
}

但是,您将如何执行此操作?使用不同的字符串来保存正则表达式模式-\\d+,[a-z]+,[a-z]+。现在,对于每个模式,编译并尝试与密码匹配。您将知道哪个正则表达式模式失败。如果没有一个失败,这意味着密码已经通过了所有规则。但是你会怎么做?使用不同的字符串来保存正则表达式模式-\\d+,[a-z]+,[a-z]+。现在,对于每个模式,编译并尝试与密码匹配。您将知道哪个正则表达式模式失败。如果没有一个失败,则表示密码已通过所有规则。这可能是一个愚蠢的问题,但在解决方案中,“?:”前面的“*”是什么意思?我只在尝试开始时使用“.*”,这不正确吗??:。。。是一个非捕获组-我将这些添加到了分组选项中?:alt1 |?:alt2-老实说,我没有检查整个过程是否在没有分组的情况下也能工作我倾向于使用比需要更多的组这是关于组的文档,捕获做了一些测试-似乎在没有分组的情况下也能工作。添加显式分组而不是依赖内置优先级只是我的一个习惯,我个人认为1+5*4比1+5*4更清晰。我正在删除上面的分组,因为它更混乱而不是有用:。。。是一个捕获组,?::。。。是一个不捕获的问题-它们几乎相同,唯一的区别是捕获组可能会被反向引用,而不捕获可能是一个潜在的愚蠢问题,但是在您的解决方案中,“?:”在“*”前面是什么意思?我只在尝试开始时使用“.*”,这不正确吗??:。。。是一个非捕获组-我将这些添加到了分组选项中?:alt1 |?:alt2-老实说,我没有检查整个过程是否在没有分组的情况下也能工作我倾向于使用比需要更多的组这是关于组的文档,捕获做了一些测试-似乎在没有分组的情况下也能工作。添加显式分组而不是依赖内置优先级只是我的一个习惯,我个人认为1+5*4比1+5*4更清晰。我正在删除上面的分组,因为它更混乱而不是有用:。。。是一个捕获组,?::。。。是非捕获组-它们几乎相同,唯一的区别是捕获组可能被反向引用,而非捕获组则不能