在以下代码中,(?i:hot)
是捕获组。或者至少应该是...它匹配表达式并使用字符。
但是,当我尝试获取组数时,它返回0。
Pattern pattern = Pattern.compile("(?i:hot)");
Matcher matcher = pattern.matcher("hot diggity dog");
while (matcher.find()) {
int groupCount = matcher.groupCount(); // returns 0
for (int i = 0; i <= groupCount; i++) {
System.out.printf("%d. %s%n", i, matcher.group(i));
}
}
括号会捕获。如您所见,如果我们这样做
matcher.replaceAll("cold")
它将返回“冷眼狗”
我希望(?i:hot)等同于((?i)hot),但事实并非如此。后一种情况是捕获组。
这不是Java RegEx Matcher.groupCount returns 0的重复项,因为在该问题中,确实没有捕获组,因此groupCount正确返回0。但是,在我的情况下,应将其视为捕获组,因为它确实可以执行捕获!
答案 0 :(得分:5)
它在documentation中:
(?idmsux-idmsux: X ) X ,作为非捕获组,其中idmsux的给定标志为开-关>
如果您想要一个捕获组,只需将其包装在另一组括号中即可:
((?i:hot))
答案 1 :(得分:2)
您正在使用?i:
。这不是要忽略大小写的提示,而是非捕获组的语法。我发现一个用例是用在正则表达式中间的(?i)来忽略后向引用\1
的大小写匹配。以下是使用它的程序的修改版本
Pattern pattern = Pattern.compile("\\b(\\w+)(\\W+(?i:\\1)\\b)+");
Matcher matcher = pattern.matcher("Hello hello");
while (matcher.find()) {
int groupCount = matcher.groupCount(); // returns 0
for (int i = 0; i <= groupCount; i++) {
System.out.printf("%d. %s%n", i, matcher.group(i));
}
}
答案 2 :(得分:1)
我希望
(?i:hot)
等同于((?i)hot)
,但事实并非如此。后一种情况是捕获组。
一旦看到相同级别的右括号,几乎所有正则表达式引擎都会关闭内联修饰符。因此,除了捕获部分外,以上两个都是等效的。
第一种语法完全是另一回事。
不应该将括号表示为捕获组或非捕获组,但是它们可以为可能捕获或不捕获的使用带来不同的功能。紧跟问号的所有左括号对于正则表达式引擎都有特殊含义:
(?...)
标记i
是修饰符。可以在正则表达式上下文之外启用修饰符,但是某些正则表达式引擎支持内联修饰符的语法,该语法使您能够在正则表达式本身中启用它们。因此,单词 inline :
(?i)test(?-i)
^ ^
E D
另一方面,还有另一种类似的语法,称为模式修改的跨度:(?modifiers:...)
,它类似于一个非捕获组(?:...)
在?
和:
之间具有一些修饰符,并将它们仅 应用于所包含的子表达式:
(?i:test)
话虽如此,(?i)test(?-i)
和(?i:test)
相等。该功能应该启用/禁用修饰符。期间。
我们不希望它有更多功能。