System.out.println(Pattern.matches("[A-Z]{1,}[a-z]{1,}[0-9]{2,}[@#$%]+[ ]*", "DEFabc45$ "));
但是当我传递像passW@ord45
这样的字符串时,它不起作用。意思是我不应该遵循这里写的正则表达式。
以下是下列条件:
编写函数boolean isValidPassword (String password)
如果密码满足以下条件,则密码有效:
答案 0 :(得分:1)
您可以使用@davide评论中链接的方法,基本上是:
(?=(?: *\\S){10})(?=.*[a-z])(?=.*[A-Z])(?=.*[$@_./-]|.*[0-9].*[0-9])
但是,在任何地方使用.*
会产生大量的回溯(特别是.*[0-9].*[0-9]
),因此防止这种情况的方法更明确:
(?=(?: *\\S){10,})(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])[^$@_./0-9-]*+(?:[$@_./-]|[0-9][^0-9]*[0-9])
关于这两种模式中使用的功能:
\\S
是一个速记字符类:所有不是空白字符
(?=...)
是一个名为lookahead的零宽度断言(测试),意味着后跟。因此,使用它可以测试来自同一位置的几个断言:(?=..)(?=..)(?=..)...
,因为不会消耗字符。
*请注意,在第二种模式中,我选择不使用前瞻,因为由于没有更多规则,消费字符并不重要。
所以每个前瞻都包含一条规则:
规则1:至少10个非空格字符
(?=
(?: *\\S){10} # a group with optional spaces and one non space character
# the group is repeated 10 times, so there are at least
# 10 characters that are not a space
)
规则2a:小写字母
(?=
[^a-z]* # zero or more characters that are not a lowercase letter
[a-z] # until a lowercase letter
)
规则2B:大写字母(与2a相同,但A-Z
)
规则3和4组合在一个子模式中,如前所述:
[^$@_./0-9-]*+ # all that is not a digit or a special character
# Note: I have added a possessive quantifier make the whole
# pattern to fail faster if the next group fails
(?: # two possibilities:
[$@_./-] # a special character
| # OR
[0-9][^0-9]*[0-9] # two digits: a digit, other characters, an other digit
)
您可以将这些模式与lookingAt
一起使用,因为无需在最后(根据您的要求)或matches
锚定它们,但您需要添加.*
最后到达字符串的末尾。