如果您一次只使用一个单词,请尝试以下操作:
boolean isMatch = s.matches(
"(?i)^(?:J()|U()|G(?!.*G)()|[GLERS]()|\\w){4,}+$\\1\\2\\3\\4");
如果您在较长的字符串中搜索匹配项:
Pattern p = Pattern.compile(
"(?i)\\b(?:J()|U()|G(?!.*G)()|[GLERS]()|\\w){4,}+\\b\\1\\2\\3\\4");
Matcher m = p.matcher(s);
while (m.find()) {
String foundString = m.group();
}
每次前四个备选方案 - J()
、或- 匹配某些内容时U()
,其后的空组“捕获”任何内容(即空字符串)。当到达字符串的末尾时,每个反向引用 - 、等 - 尝试匹配其对应组匹配的相同内容:不再匹配。 G()
[GLERS]()
\1
\2
显然,这将永远成功;你总是可以匹配注意到。诀窍是如果其对应的组没有参与匹配,则反向引用甚至不会尝试匹配。也就是说,如果j
目标字符串中没有,()
则J()
替代项中的永远不会涉及。当正则表达式引擎\1
稍后处理反向引用时,它会立即报告失败,因为它知道该组没有参与匹配。
这样,空组就像一个复选框,反向引用确保所有的复选框都被选中。不过,有一点皱纹。theG()
和[GLERS]()
Alternatives 都可以匹配g
;当你需要他们时,你如何确保他们都参加比赛?我尝试的第一个正则表达式,
"(?i)^(?:J()|U()|G()|[GLERS]()|\\w){4,}+$\\1\\2\\3\\4"
...未能匹配“jugg”这个词,因为G()
替代方案是同时使用两个g
's; [GLERS]()
从来没有机会参加。所以我添加了否定的lookahead - (?!.*G)
- 现在它只匹配最后一个 g
。如果我有三个可以匹配 a 的替代方案g
,我将不得不添加(?!.*G.*G)
到第一个和(?!.*G)
第二个。但实际上,在我到达那一点之前,我可能会改用另一种方法(可能是一种不涉及正则表达式的方法)。;)