【问题标题】:Java - Regex for PasswordJava - 密码的正则表达式
【发布时间】:2012-05-02 22:48:35
【问题描述】:

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

我已经尝试过这个并得到了类似的东西:".*\\d.*[a-z].*[A-Z].*" 但这要求数字在前,小写在后,大写在后。

【问题讨论】:

标签: java regex


【解决方案1】:

你的用例不是正则表达式特别擅长的一种——如果你被正则表达式卡住了,我猜你别无选择,只能列举 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;
        }
    }
}

【讨论】:

  • 可能是个愚蠢的问题,但你的解决方案中的 '.*' 前面的 '?:' 是什么意思?我只在尝试开始时使用'.*',这不正确吗?
  • (?: ... ) 是一个非捕获组 - 我添加了这些组来分组替代 (?:alt1)|(?:alt2) - 老实说,我没有检查整个事情在没有分组的情况下也能工作(我倾向于使用比需要更多的组)
  • 这里是关于组和捕获docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…的文档
  • 做了一些测试 - 似乎也可以在没有组的情况下工作。添加显式分组而不是依赖内置优先级只是我的一个习惯(不限于正则表达式),我个人发现 1+(5*4) 比 1+5*4 更清晰。我正在删除上面的分组,因为它比有用更令人困惑:)
  • ( ... ) 是一个捕获组, (?: ... ) 是一个非捕获组 - 它们几乎相同,唯一的区别是捕获组可能被反向引用, 而非捕获不能
【解决方案2】:

实现这一点的一种方法是通过

1) 首先使用 a 来检查是否存在小写字母 单独的正则表达式,比如 regex-1。

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

3) 检查任何其他规则。

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

【讨论】:

  • 你会怎么做呢?
  • 拥有不同的字符串来保存正则表达式模式-"\\d+"、"[a-z]+"、"[A-Z]+"。现在对于每个模式,编译并尝试与密码匹配。你会知道哪个正则表达式模式失败了。如果都没有失败,说明密码通过了所有规则。
【解决方案3】:

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

(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
);

【讨论】:

    猜你喜欢
    • 2023-02-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2021-09-15
    相关资源
    最近更新 更多