我正在尝试使用正则表达式在Java中实现Azure AD cloud user account policy。
我已经定义了模式字符串,并且按如下方式使用string.matches(pattern):
// ONE OF THESE CHARACTER CLASS COMBINATIONS NEED TO BE MET
// combination of lowercase, uppercase and numbers, 8 to 16 characters in length
// combination of lowercase, uppercase and symbols, 8 to 16 characters in length
// combination of lowercase, numbers and symbols, 8 to 16 characters in length
// combination of uppercase, numbers and symbols 8 to 16 characters in length
private static final String PATTERN_PASSWORD_REGEX = new StringBuilder('^')
.append("((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])).{8,16}")
.append('|') // -or-
.append("((?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&*\\-_!+=\\[\\]{}|\\:‘,.?\\/`~“\\(\\);])).{8,16}")
.append('|') // -or-
.append("((?=.*[a-z])(?=.*[0-9])(?=.*[@#$%^&*\\-_!+=\\[\\]{}|\\:‘,.?\\/`~“\\(\\);])).{8,16}")
.append('|') // -or-
.append("((?=.*[A-Z])(?=.*[0-9])(?=.*[@#$%^&*\\-_!+=\\[\\]{}|\\:‘,.?\\/`~“\\(\\);])).{8,16}")
.append('$')
.toString();
public static boolean validate(String password) {
return password.matches(PATTERN_PASSWORD_REGEX);
}
以某种方式,即使我在正则表达式中没有 ,它也将空格视为特殊字符。下面的JUnit测试方法将传递除最后一个以外的所有断言。
@Test
public void testPassword() {
Assert.assertTrue("password is valid", validate("Abcdef12"));
Assert.assertTrue("password is valid", validate("abcde$12"));
Assert.assertTrue("password is valid", validate("ABCDE%12"));
Assert.assertTrue("password is valid", validate("Abcde~12"));
Assert.assertFalse("password is invalid", validate("abcdefgh"));
Assert.assertFalse("password is invalid", validate("12345678"));
Assert.assertFalse("password is invalid", validate("ABCDEFGH"));
Assert.assertFalse("password is invalid", validate("ABCDefgh"));
Assert.assertFalse("password is invalid", validate("!~$:-_@&"));
// This assertion fails...
Assert.assertFalse("password is invalid", validate("Abcdef 12"));
}
关于SO的正则表达式问题,我看到了非常优雅的答案,但通常它们不涉及字符类组合。希望有人能告诉我我做错了什么,或者是否有更好的方法可以做到这一点。
答案 0 :(得分:1)
您需要指定最后一部分中允许的字符,而不是点。将.{8,16}
替换为[-A-Za-z0-9@#$%^&*_!+=\[\]{}|:',.?/`~\"();]{8,16}
:
^(?:
(?=.*[a-z])(?=.*[A-Z])(?=.*\d)
|
(?=.*[a-z])(?=.*[A-Z])(?=.*[-@#$%^&*_!+=\[\]{}|:',.?/`~"();])
|
(?=.*[a-z])(?=.*\d)(?=.*[-@#$%^&*_!+=\[\]{}|:',.?/`~"();])
|
(?=.*[A-Z])(?=.*\d)(?=.*[-@#$%^&*_!+=\[\]{}|:',.?/`~"();])
)
[-A-Za-z0-9@#$%^&*_!+=\[\]{}|:',.?/`~"();]{8,16}
$
请参见regex demo。
private static final String PATTERN_PASSWORD_REGEX = new StringBuilder('^(?:')
.append("(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=[^0-9]*[0-9])")
.append('|') // -or-
.append("(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])(?=.*[-@#$%^&*_!+=\\[\\]{}|:‘,.?/`~“();])")
.append('|') // -or-
.append("(?=[^a-z]*[a-z])(?=[^0-9]*[0-9])(?=.*[-@#$%^&*_!+=\\[\\]{}|:‘,.?/`~“();])")
.append('|') // -or-
.append("(?=[^A-Z]*[A-Z])(?=[^0-9]*[0-9])(?=.*[-@#$%^&*_!+=\\[\\]{}|:‘,.?/`~“();])")
.append(')[-A-Za-z0-9@#$%^&*_!+=\\[\\]{}|:‘,.?/`~“();]{8,16}$')
.toString();