一、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)一致。