我最近在使用Java Regular Expression时遇到了一个奇怪的错误:
System.out.println(Pattern.matches("(\\d\\d)", "12")); --> true
System.out.println(Pattern.matches("(\\d\\d)", "11")); --> true
System.out.println(Pattern.matches("(\\d\\d)\\1", "1212")); --> true
System.out.println(Pattern.matches("(\\d\\d)\\1", "1122")); --> false
最后一个错了什么?任何人都可以帮助我,非常感谢〜
答案 0 :(得分:4)
在第三行:
Pattern.matches("(\\d\\d)\\1", "1212")
+------+
12
captured group为12.所以\1
包含12,而12 = 12则为真。
在第四行:
Pattern.matches("(\\d\\d)\\1", "1122")
+------+
11
被捕获的组是11.所以\1
继续11,从11!= 22,你得到假。
答案 1 :(得分:3)
\1
是前一场比赛的占位符。
最后一个例子的匹配将是“11”
所以\ 1变为“11”,与下两位“22”不匹配。
答案 2 :(得分:3)
我认为您将backreference与limiting quantifier
混淆了反向引用与先前与捕获组匹配的文本匹配。
和
[有]额外的量词,可让您指定令牌重复的次数
因此,为了匹配分组子模式的两次出现,只需使用{2}
:
System.out.println(Pattern.matches("(\\d\\d){2}", "1212")); // --> true
System.out.println(Pattern.matches("(\\d\\d){2}", "1122")); // --> true
请参阅IDEONE demo
或者,如果这些子模式不相邻,则从块动态构建模式:
String digits = "\\d\\d";
String myRegex = "\\b(?:" + digits + " word|word " + digits + ")\\b";
答案 3 :(得分:2)
11
!= 22
....
这是最后一个错误。
\1
代表重复的群组。群组有11
,因此\1
期望11
而不是22
。