【发布时间】:2012-05-02 22:48:35
【问题描述】:
如何构造一个正则表达式,使我正在制作的密码字段包含至少一个数字、至少一个小写字母和至少一个大写字母,其中顺序无关紧要,并且这些字符之间可以有任何内容?
我已经尝试过这个并得到了类似的东西:".*\\d.*[a-z].*[A-Z].*"
但这要求数字在前,小写在后,大写在后。
【问题讨论】:
如何构造一个正则表达式,使我正在制作的密码字段包含至少一个数字、至少一个小写字母和至少一个大写字母,其中顺序无关紧要,并且这些字符之间可以有任何内容?
我已经尝试过这个并得到了类似的东西:".*\\d.*[a-z].*[A-Z].*"
但这要求数字在前,小写在后,大写在后。
【问题讨论】:
你的用例不是正则表达式特别擅长的一种——如果你被正则表达式卡住了,我猜你别无选择,只能列举 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;
}
}
}
【讨论】:
实现这一点的一种方法是通过
1) 首先使用 a 来检查是否存在小写字母 单独的正则表达式,比如 regex-1。
2) 接下来使用另一个正则表达式检查它是否包含数字。
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
);
【讨论】: