java中正则表达式Pattern与Matcher类使用详解(find、group)

    xiaoxiao2023-11-03  161

    一、Pattern的使用

    这个使用很简单。

    1、把正则表达式编译为Pattern对象:

    比如:

    Pattern compile = Pattern.compile("http://([a-z]+\\.)+[a-z]+");

    就是用于匹配http的url的正则表达式(随手写的,可能有bug),利用compile静态方法创建对应的Pattern实例对象。

    2、Pattern里面两个有用的方法是split和matcher方法:

    (1)split方法与String类的split方法一样,根据正则表达式分割字符串的;

    (2)matcher方法是用于获取Matcher对象的,需要传入要被操作的字符串:

    二、Matcher类的使用

    一般情况下Matcher对象实例时通过Pattern的实例对象调用matcher方法创建的。。当然,也可以new一个,是一样的效果,还是用Pattern的matcher方法创建Matcher对象更好;可以看看Pattern.matcher方法的源码:

    public Matcher matcher(CharSequence input) { if (!compiled) { synchronized(this) { if (!compiled) compile(); } } Matcher m = new Matcher(this, input); return m; }

    find方法与group、start、end等方法是一起使用的。

    find有无参与有参两种,底层都是调用search方法实现的:

    (1)search方法

    search方法需要一个整形的参数,用于指定从源字符串的哪个位置开始进行匹配。

    当匹配到字串符合正则表达式的要求后,就会停止匹配,此时会记录下该字串的位置信息。方便给group、start、end等方法使用。

    (2)find有参方法

    是通过调用search方法实现的,只不过在find方法中检测了边界。

    然后就是把find的参数传给search进行匹配了。

    (3)find无参方法

    无参方法对比有参方法区别不大。只是无参方法会自动 以上一次匹配成功的子串的下一个字符索引 作为search的参数,然后开始匹配。(功能类似于iterator迭代器的next)

    举个例子:

    //源字符串,有http的url,有邮箱,有手机号(瞎编的,别发信息) String sourceStr = "http://www.baidu.com http://www.sina.com 1147391211@qq.com http://www.tencent.com " + "18521716520"; //正则表达式为: Pattern compile = Pattern.compile("http://([a-z]+\\.)+[a-z]+");

    <1>第一次调用find无参方法时,是使用search(0),直到成功匹配一次,或者没匹配到为止。

    (分别使得find方法返回trure或者false)

    根据例子,匹配成功的字符串为:http://www.baidu.com (也就是这个时候使用matcher.group获取的字符串)

    这子串在源字符串的索引是从0~19。

     

    <2>第二次调用find无参方法时,search的参数为上一步中匹配的子串的下一个字符的索引,即search(20)。直到成功匹配一次,或者没匹配到为止。(分别使得find方法返回trure或者false)

    根据例子,匹配成功的字符串为:http://www.sina.com (也就是这个时候使用matcher.group获取的字符串)

    这字串在源字符串的索引是从21~40。

    可能会有疑问,第20个字符去哪了?可以去看看源字符串,第20个字符是个空格,并不会被我的正则表达式匹配到,所以会跳过。

    <3>第三次调用find无参方法时,与第<2>步原理一样...

    .........

    (4)group无参方法

    该方法的结果是获取find方法调用后,匹配成功(find返回true时)的子串。如果find方法返回false,说明没找到子串,此时调用group会抛异常。

    (5)group有参方法与groupCount()

    参数是整数。比如group(n),用于获取find匹配成功的子串中,被正则表达式中第n个子表达式匹配的最后一个字符串;

    例子:

    //源字符串,有http的url,有邮箱,有手机号(瞎编的,别发信息) String sourceStr = "http://www.baidu.com http://www.sina.com 1147391211@qq.com http://www.tencent.com " + "18521716520"; //正则表达式为: Pattern compile = Pattern.compile("http://([a-z]+\\.)+[a-z]+"); Matcher matcher = compile.matcher(sourceStr); matcher.find(); System.out.println(matcher.group()); System.out.println(matcher.groupCount()); System.out.println(matcher.group(1));

    上面代码中,matcher调用完find方法后,此时匹配的字符串是http://www.baidu.com。

    所以matcher.group()的返回值就是:http://www.baidu.com。

    matcher.groupCount()方法返回的是正则表达式的子表达式数量,即正则表达式中有多少对小括号()包含的子表达式。

    matcher.group(1)的返回值是baidu.。

    matcher.group(1)怎么获取的呢?

    参数为1,表示把当前find匹配的整个子串(http://www.baidu.com)作为源字符串,然后从该源字符串中获取能够被原始正则表达式(http://([a-z]+\\.)+[a-z]+)中的第1个子正则表达式([a-z]+\\.)匹配成功的子串,匹配成功的字串有多个时,返回最后一个匹配成功的子串。

    也就是说,http://www.baidu.com这串字符串中,能被([a-z]+\\.)匹配的有两个字串,分别是www.和baidu.,但group(1)返回的是最后一个字串,即baidu. 

    (6)start无参  和  end无参

    start无参获取的是当前group的字串在源字符串中的开始索引。

    end无参获取的是当前group的字串在源字符串中的结束索引。

    (7)start有参  和 end有参

    参数作用与group的参数作用一致,其他的作用与(6)一致。

     

    最新回复(0)