Java 正则表达式:捕获组与非捕获组

初学Java,接触到正则表达式的时候,非常困惑是如何匹配到指定的字段的,直到看到了捕获组与非捕获组的概念。。。

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

转载于:https://www.cnblogs.com/leewbl/p/7379766.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值