尽管我个人会使用Mark
Rhodes提供的解决方案,但这样做可以实现Java中作为单个正则表达式所需的功能。随着规则变得更加复杂,这将变得非常荒谬(如果还没有…)。
String regex = "^(?=.*?\p{Lu})(?=.*?[\p{L}&&[^\p{Lu}]])(?=.*?\d)" + "(?=.*?[`~!@#$%^&*()\-_=+\\\|\[{\]};:'",<.>/?]).*$"^这匹配字符串的开头。并非一定要做到这一点,但我发现它有助于提高可读性和理解力。此外,在可能的情况下使用它通常可以大大提高性能,并且几乎永远不会受到损失。
(?= X )这称为正向超前。基本上就是我们说的是“字符串(^)的开始必须跟这件事 X 为了一场比赛,但 不要 使光标移动到结束 X ,留在该行的开头。(这就是“展望未来”部分。)
。*? p {Lu}在行的开头吃掉字符,直到找到大写字母为止。如果找不到大写字母,将无法匹配。我们使用 p {Lu}而不是AZ是因为我们不希望世界其他地区的人举起手来抱怨我们的软件是由一个无知的美国人编写的。
现在,我们回到该行的开头(之所以返回,是因为我们使用了超前功能),并开始搜索。*?[ p {L} && [^ p {Lu}]]速记,表示“所有字母,减去大写字母”(因此匹配小写字母)。
。? d +。?[`〜!@#$%^&*() -_ = + \ | [{\}};:’“,<。> /?]重复用于数字和特殊字符列表。
。* $匹配所有其他内容,直到该行的末尾。我们这样做只是因为Java中“ matches”方法的语义,该方法查看 整个 字符串是否与正则表达式匹配。您可以离开这一部分,并使用Matcher#find()方法获得相同的结果。
猫头鹰是有关任何技术主题的最佳书籍之一。 而且读起来又短又快。我不能推荐它。



