我必须匹配一个8字符串,该字符串可以包含正好2个字母(1个大写字母和1个小写字母)以及正好6个数字,但是它们可以任意排列。
因此,基本上:
我尝试使用正向前瞻来确保该字符串包含数字,大写和小写字母,但是在将其限制为一定数目的出现时遇到了麻烦。我想我可以通过包括字母和数字可能出现的位置的所有可能组合来解决这个问题:
(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z]) ([A-Z][a-z][0-9]{6})|([A-Z][0-9][a-z][0-9]{5})| ... | ([0-9]{6}[a-z][A-Z])
但这是一种非常round回的方式,我想知道是否有更好的解决方案。
您可以使用
^(?=[^A-Z]*[A-Z][^A-Z]*$)(?=[^a-z]*[a-z][^a-z]*$)(?=(?:\D*\d){6}\D*$)[a-zA-Z0-9]{8}$
参见regex演示(由于多行输入而有些修改)。在Java中,不要忘记使用双反斜杠(例如\\d,匹配一个数字)。
\\d
这是一个细分:
^
(?=[^A-Z]*[A-Z][^A-Z]*$)
\p{Lu}
\P{Lu}
(?=[^a-z]*[a-z][^a-z]*$)
\p{Ll}
\P{Ll}
(?=(?:\D*\d){6}\D*$)
\D
[^0-9]
\d
\D*
$
[a-zA-Z0-9]{8}
按照逻辑,我们甚至可以将其简化为
^(?=[^a-z]*[a-z][^a-z]*$)(?=(?:\D*\d){6}\D*$)[a-zA-Z0-9]{8}$
可以删除一个条件,因为我们只允许使用大小写字母和数字[a-zA-Z0-9],并且当我们应用2个条件时, 匹配 字符串时会自动执行第三个条件(在这种情况下,一个字符必须为大写)。
[a-zA-Z0-9]
当将它与Java matches()方法一起使用时^,无需$在模式的开头和结尾处使用和定位符,但是在前瞻中仍然需要它:
matches()
String s = "K82v6686"; String rx = "(?=[^a-z]*[a-z][^a-z]*$)" + // 1 lowercase letter check "(?=(?:\\D*\\d){6}\\D*$)" + // 6 digits check "[a-zA-Z0-9]{8}"; // matching 8 alphanum chars exactly if (s.matches(rx)) { System.out.println("Valid"); }