^。(?= {15,})(?=。 \ d)(?= [AZ])(?=。 [AZ] )(= ?。[@#$%^&安培;! + =])* $
这是我目前正在使用的正则表达式,它将评估每个中的1个:我选择的上限,下限,数字和特价。我的问题是如何检查每个中的2个?我也问,因为我不知道是否只是在评估它需要的第一组标准,因此为此编写测试用例似乎很困难。这是一个密码,但要求是它需要基于我们正在使用的包的正则表单形式。
修改
好吧,我急于验证表达式,我忘了验证字符串长度。感谢Ken和Gumbo帮我解决这个问题。
这是我正在执行的代码:
我道歉,因为正则表达式不是我的区域。
我使用的密码是以下字符串“$$ QiouWER1245”,我目前正在经历的行为是它随机选择通过或失败。有什么想法吗?
Pattern pattern = Pattern.compile(regEx);
Matcher match = pattern.matcher(password);
while(match.find()){
System.out.println(match.group());
}
从我看到它的评估结果为true,它会将密码中的值返回给我,否则它是一个空字符串。
答案 0 :(得分:3)
就个人而言,我认为强制使用所有三个字符类的密码策略并不是很有用。通过让人们制作更长的密码,您可以获得相同程度的随机性。如果用户必须遵守太多的密码规则(这会使密码难以记住),用户往往会感到沮丧并写下密码。我建议计算一些熵,并确保它们大于60(通常需要10-14个字符的密码)。每个字符的熵大致取决于字符的数量,它们使用的字符集的范围,以及它们在字符集之间切换的频率(我猜想像HEYthere这样的密码比heYThEre更容易预测)。
另一个注意事项:你打算不计算键盘右边的符号(句号,逗号,尖括号等)吗?
如果您仍然需要找到两个字符的组,为什么不重复每个模式?例如,将(?=。 \ d)设为(?=。 \ d。* \ d)。
对于您的测试用例,如果您担心它只会检查第一个标准,那么请编写一个测试用例,确保以下每个密码都失败(因为在每种情况下都不符合一个且只有一个标准):为了好玩,我颠倒了每个字符集的期望顺序,尽管除非有人在将来某个日期删除/忘记?=,否则它可能不会有所作为。
!@#TESTwithoutnumbers
TESTwithoutsymbols123
&*(testwithoutuppercase456
+_^TESTWITHOUTLOWERCASE3498
我应该指出,从技术上讲,这些密码都不应该被接受,因为它们使用字典单词,每个字符有大约2位熵,而不是更像6的东西。但是,我意识到编写一个(可维护的)很难高效的)正则表达式来检查词典单词。
答案 1 :(得分:2)
试试这个:
"^(?=(?:\\D*\\d){2})(?=(?:[^a-z]*[a-z]){2})(?=(?:[^A-Z]*[A-Z]){2})(?=(?:[^!@#$%^&*+=]*[!@#$%^&*+=]){2}).{15,}$"
此处非捕获组(?:…)
用于对条件进行分组并重复它们。我还使用了每个字符类的补码进行优化,而不是通用的.
。
答案 2 :(得分:2)
如果我正确理解您的问题,您至少需要15个字符,并且要求至少2个大写字符,至少2个小写字符,至少2个数字和至少2个特殊字符。在这种情况下你可以这样:
^.*(?=.{15,})(?=.*\d.*\d)(?=.*[a-z].*[a-z])(?=.*[A-Z].*[A-Z])(?=.*[!@#$%^&*+=].*[!@#$%^&*+=]).*$
顺便说一句,你的原始正则表达式在\ d 之前有一个额外的反斜杠
答案 3 :(得分:1)
我不确定一个大正则表达式是否是正确的方法。它看起来已经过于复杂,将来很难改变。
我的建议是按以下方式构建代码:
这也将允许您传递返回代码或错误字符串,指定为什么不接受密码,代码将更加简单。