我必须匹配一个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])
Run Code Online (Sandbox Code Playgroud)
但这是一种非常迂回的方式,我想知道是否有更好的解决方案.
您可以使用
^(?=[^A-Z]*[A-Z][^A-Z]*$)(?=[^a-z]*[a-z][^a-z]*$)(?=(?:\D*\d){6}\D*$)[a-zA-Z0-9]{8}$
Run Code Online (Sandbox Code Playgroud)
请参阅正则表达式演示(由于多行输入而稍有修改).在Java中,不要忘记使用双反斜杠(例如\\d匹配数字).
这是一个细分:
^ - 字符串的开头(假设不使用多行标志)(?=[^A-Z]*[A-Z][^A-Z]*$)- 检查是否只有1个大写字母(用于\p{Lu}匹配任何Unicode大写字母并\P{Lu}匹配除此之外的任何字符)(?=[^a-z]*[a-z][^a-z]*$)- 类似检查是否只有1个小写字母(或者,使用\p{Ll}和\P{Ll}匹配Unicode字母)(?=(?:\D*\d){6}\D*$)- 检查字符串中是否有六位数字(=从字符串的开头,可以有0个或更多的非数字符号(\D匹配任何字符,但也可以替换[^0-9]为数字),然后是数字(\d)然后是0或更多的非数字字符(\D*),直到string($)的结尾然后[a-zA-Z0-9]{8} - 恰好匹配8个字母数字字符.$ - 字符串结尾.按照逻辑,我们甚至可以减少这一点
^(?=[^a-z]*[a-z][^a-z]*$)(?=(?:\D*\d){6}\D*$)[a-zA-Z0-9]{8}$
Run Code Online (Sandbox Code Playgroud)
可以删除一个条件,因为我们只允许使用小写和大写字母和数字[a-zA-Z0-9],当我们应用2个条件时,第3个条件会在匹配字符串时自动执行(在这种情况下,一个字符必须是大写).
在Java 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");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7052 次 |
| 最近记录: |