捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式 (dog) 创建了单一分组,组里包含"d","o",和"g"。
捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
在Java正则表达式的相关类Matcher中,有如下几个方法:
- int groupCount()
- String group(int group)
- int start(int group)
- int end(int group)
- String group(String name)
- int start(String name)
- int end(String name)
例子Demo1:
String text = "John writes about this, and John Doe writes about that,"
+ " and John Wayne writes about everything.";
String patternString = "(John) (.+?) ";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
matcher.find();//匹配字符串,匹配到的字符串可以在任何位置
int start = matcher.start();//返回当前匹配到的字符串在原目标字符串中的位置
int end = matcher.end();//返回当前匹配的字符串的最后一个字符在原目标字符串中的索引位置
System.out.println("found group: group(0) is '" + matcher.group(0));
System.out.println("found group: group(1) is '" + matcher.group(1) + "',group(2) is '" + matcher.group(2)+"'");
patternString= "(?:John)";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
System.out.println("groupCount is -->" + matcher.groupCount());
while (matcher.find()) {
System.out.println("found: " + matcher.group(1));
}
运行结果:
found group: group(0) is ‘John writes
found group: group(1) is ‘John’,group(2) is ‘writes’
groupCount is –>0
Exception in thread “main” java.lang.IndexOutOfBoundsException: No group 1
从输出结果可以看出,当正则表达式包含多个group时,也就是含有多个’(pattern)’格式的子表达式时,它的分组索引(group number)是从1开始的,而group(0)代表了整个匹配的字符串.
总结:
(1)正则表达式中以'()'标记的子表达式所匹配的内容就是一个分组(group),分组索引是从1开始的,0代表正则表达式匹配的整个字符串,group(i)代表第i组匹配的内容。
(2)groupCount() 函数返回当前正则表达式中分组的个数。
(3)类似于(?:pattern)格式的子表达式不能算是一个分组。
例子Demo2:
String text = "John writes about this, and John Doe writes about that,"
+ " and John Wayne writes about everything.";
String patternString = "(John) (.+?) ";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
matcher.find();//匹配字符串,匹配到的字符串可以在任何位置
int start = matcher.start();//返回当前匹配到的字符串在原目标字符串中的位置
System.out.println(start);//0
int end = matcher.end();//返回当前匹配的字符串的最后一个字符在原目标字符串中的索引位置
System.out.println(end);//12
start = matcher.start(1);//第一个分组匹配的内容,也就是John开始的索引位置,0
System.out.println(start);//0
start = matcher.start(2);//第一个分组匹配的内容,也就是writes开始的索引位置,5
System.out.println(start);//5
end = matcher.end(1);//第一个分组匹配的内容,也就是John结束的索引位置,4
System.out.println(end);//4
end = matcher.end(2);//第二个分组匹配的内容,也就是writes开始的索引位置,12
System.out.println(end);//12
start = matcher.start(3);//Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 3
总结:
(1)当索引大于正则表达式中实际存在的索引数量,也就是groupCount()返回值时会抛出异常。
(2)int start(int group) 返回当前分组匹配到的字符串在原目标字符串中的位置。
(3)返回当前分组匹配的字符串的最后一个字符在原目标字符串中的索引位置。
参考链接:
1.https://blog.csdn.net/yin380697242/article/details/52097679
2.http://www.runoob.com/java/java-regular-expressions.html