1.捕获组
直接给出例子:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Catch_group {
public static void main(String[] args){
String str = "https://i.cnblogs.com/EditPosts.aspx?postid=7379766";
String regex = "(https.*\\?)(p.*=)(\\d*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
if(matcher.find()){
System.out.printf("%s\n%s\n%s\n%s\n%s",matcher.group(0),
matcher.group(1),
matcher.group(2),
matcher.group(3));
}
}
output:
https://i.cnblogs.com/EditPosts.aspx?postid=7379766
https://i.cnblogs.com/EditPosts.aspx?
postid=
7379766
正则表达式 regex = "(https.*\\?)(p.*=)(\\d*)" 被划分成了四个捕获组,第一个默认为匹配到的字符串整体,第二个为(https.*\\?) 第三个为(p.*=) 第四个为(\\d*)。
当含有多重括号时,按照先外后里,同级括号从左至右的顺序完成捕获组匹配。
例如,在表达式((A)((B)(C))),有五个这样的组: ((A)((B)(C))) (A) ((B)(C)) (B) (C)
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中,例如此处,matcher.group(0)和matcher.group(1)都为整个字符串。
当regex = (https.*\\?)((p.*=)(\\d*))时,groupCount为4(最外侧并没有圆括号):
https://i.cnblogs.com/EditPosts.aspx?postid=7379766
https://i.cnblogs.com/EditPosts.aspx?
postid=7379766
postid=
7379766
2.非捕获组
非捕获组的具体语法是把()用(?:)代替,表示这个组是非捕获的,不在matcher.group中。如果我想只捕获数字字符串“7379766”,那么把其他都设置成非捕获组,然后只在最内侧(\\d*)设置成捕获组。多重括号同理,如果想捕获C,那么"(A)((B)(C))"应改为"(?:A)(?:(?:B)(C))"
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Catch_group {
public static void main(String[] args){
String str = "https://i.cnblogs.com/EditPosts.aspx?postid=7379766";
String regex = "(?:https.*\\?)(?:p.*=)(\\d*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
if(matcher.find()) System.out.printf("%s\n%s",matcher.group(0),
matcher.group(1));
}
}
output:
https://i.cnblogs.com/EditPosts.aspx?postid=7379766
7379766