我对创建复杂的RegEx并不是很好。我从其他来源复制了以下内容,以便对应用程序强制实施某些密码限制:
// 8 to 20 char, one digit, one letter
public static final String GOOD_PASSWORD_REGEX =
"(^(?=.{8,20})(?=.*[a-zA-Z])(?=.*[\\d]).*$)";
同时,这个单元测试失败了:
String tooLongPassword = "asdfghjkl123456789qwe"; // 21 characters
assertFalse(tooLongPassword.matches(ValidationContants.GOOD_PASSWORD_REGEX));
这是我针对此RegEx运行的少数类似测试案例之一,其中包括没有字母,没有数字等的其他测试用例,其余的都通过。
请问错误在哪里?
答案 0 :(得分:1)
在您的版本中,前瞻断言仅检查它是否可以匹配字符串开头的8-20个字符长度的字符串。这当然也可以成为一个长度为21或以上的字符串。
所以$
需要成为前瞻的一部分:
// 8 to 20 char, one digit, one letter
public static final String GOOD_PASSWORD_REGEX =
"(^(?=.{8,20}$)(?=.*[a-zA-Z])(?=.*\\d).*$)";
但为什么要在密码上加上最大长度?此外,[]
快捷方式周围的\d
也是不必要的。
此外,由于您只需要正则表达式来验证密码,而不是实际返回它(因为它现在设置的方式将返回整个输入字符串),您可以将正则表达式缩短为:
"^(?=.{8,20}$)(?=.*[a-zA-Z])(?=.*\\d)"