JAVA正则表达式:Pattern类与Matcher类详解(转)
是⼀个⽤正则表达式所订制的模式来对字符串进⾏匹配⼯作的类库包。它包括两个类:Pattern和Matcher Pattern ⼀个Pattern 是⼀个正则表达式经编译后的表现模式。 Matcher ⼀个Matcher对象是⼀个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查。⾸先⼀个Pattern实例订制了⼀个所⽤语法与PERL的类似的正则表达式经编译后的模式,然后⼀个Matcher实例在这个给定的Pattern实例的模式控制下进⾏字符串的匹配⼯作。
以下我们就分别来看看这两个类:
⼀、捕获组的概念
捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:
1        ((A)(B(C)))
2        (A)
正则匹配方法3        (B(C))
4        (C)
组零始终代表整个表达式。以 (?) 开头的组是纯的⾮捕获组,它不捕获⽂本,也不针对组合计进⾏计数。
与组关联的捕获输⼊始终是与组最近匹配的⼦序列。如果由于量化的缘故再次计算了组,则在第⼆次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串"aba" 与表达式(a(b)?)+ 相匹配,会将第⼆组设置为 "b"。在每个匹配的开头,所有捕获的输⼊都会被丢弃。
⼆、详解Pattern类和Matcher类
java正则表达式通过包下的Pattern类与Matcher类实现(建议在阅读本⽂时,打开java API⽂档,当介绍到哪个⽅法时,查看java API中的⽅法说明,效果会更佳).
Pattern类⽤于创建⼀个正则表达式,也可以说创建⼀个匹配模式,它的构造⽅法是私有的,不可以直接创建,但可以通过Patternplie(String regex)简单⼯⼚⽅法创建⼀个正则表达式,
Java代码⽰例:
Pattern p=Patternpile("\\w+");
p.pattern();//返回 \w+
pattern() 返回正则表达式的字符串形式,其实就是返回Patternplile(String regex)的regex参数
1.Pattern.split(CharSequence input)
Pattern有⼀个split(CharSequence input)⽅法,⽤于分隔字符串,并返回⼀个String[],我猜String.split(String regex)就是通过
Pattern.split(CharSequence input)来实现的.
Java代码⽰例:
Pattern p=Patternpile("\\d+");
String[] str=p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa");
结果:str[0]="我的QQ是:" str[1]="我的电话是:" str[2]="我的邮箱是:aaa@aaa"
2.Pattern.matcher(String regex,CharSequence input)是⼀个静态⽅法,⽤于快速匹配字符串,该⽅法适合⽤于只匹配⼀次,且匹配全部字符串.
Java代码⽰例:
Pattern.matches("\\d+","2223");//返回true
Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这⾥aa不能匹配到
Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这⾥bb不能匹配到
3.Pattern.matcher(CharSequence input)
说了这么多,终于轮到Matcher类登场了,Pattern.matcher(CharSequence input)返回⼀个Matcher对象.
Matcher类的构造⽅法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)⽅法得到该类的实例.
Pattern类只能做⼀些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher⼀起合作.Matcher类提供了对正则表达式的分组⽀持,以及对正则表达式的多次匹配⽀持.
Java代码⽰例:
Pattern p=Patternpile("\\d+");
Matcher m=p.matcher("22bb23");
m.pattern();//返回p 也就是返回该Matcher对象是由哪个Pattern对象的创建的
4.Matcher.matches()/ Matcher.lookingAt()/ Matcher.find()
Matcher类提供三个匹配操作⽅法,三个⽅法均返回boolean类型,当匹配到时返回true,没匹配到则返回false
matches()对整个字符串进⾏匹配,只有整个字符串都匹配了才返回true
Java代码⽰例:
Pattern p=Patternpile("\\d+");
Matcher m=p.matcher("22bb23");
m.matches();//返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功.
Matcher m2=p.matcher("2223");
m2.matches();//返回true,因为\d+匹配到了整个字符串
我们现在回头看⼀下Pattern.matcher(String regex,CharSequence input),它与下⾯这段代码等价
Patternpile(regex).matcher(input).matches()
lookingAt()对前⾯的字符串进⾏匹配,只有匹配到的字符串在最前⾯才返回true
Java代码⽰例:
Pattern p=Patternpile("\\d+");
Matcher m=p.matcher("22bb23");
m.lookingAt();//返回true,因为\d+匹配到了前⾯的22
Matcher m2=p.matcher("aa2223");
m2.lookingAt();//返回false,因为\d+不能匹配前⾯的aa
find()对字符串进⾏匹配,匹配到的字符串可以在任何位置.
Java代码⽰例:
Pattern p=Patternpile("\\d+");
Matcher m=p.matcher("22bb23");
m.find();//返回true
Matcher m2=p.matcher("aa2223");
m2.find();//返回true
Matcher m3=p.matcher("aa2223bb");
m3.find();//返回true
Matcher m4=p.matcher("aabb");
m4.find();//返回false
5.Mathcer.start()/ d()/ up()
当使⽤matches(),lookingAt(),find()执⾏匹配操作后,就可以利⽤以上三个⽅法得到更详细的信息.
start()返回匹配到的⼦字符串在字符串中的索引位置.
end()返回匹配到的⼦字符串的最后⼀个字符在字符串中的索引位置.
group()返回匹配到的⼦字符串
Java代码⽰例:
Pattern p=Patternpile("\\d+");
Matcher m=p.matcher("aaa2223bb");
m.find();//匹配2223
m.start();//返回3
Mathcer m2=m.matcher("2223bb");
m.lookingAt();  //匹配2223
m.start();  //返回0,由于lookingAt()只能匹配前⾯的字符串,所以当使⽤lookingAt()匹配时,start()⽅法总是返回0
Matcher m3=m.matcher("2223bb");
m.matches();  //匹配整个字符串
m.start();  //返回0,原因相信⼤家也清楚了
说了这么多,相信⼤家都明⽩了以上⼏个⽅法的使⽤,该说说正则表达式的分组在java中是怎么使⽤的.
start(),end(),group()均有⼀个重载⽅法它们是start(int i),end(int i),group(int i)专⽤于分组操作,Mathcer类还有⼀个groupCount()⽤于返回有多少组.
Java代码⽰例:
Pattern p=Patternpile("([a-z]+)(\\d+)");
Matcher m=p.matcher("aaa2223bb");
m.find();  //匹配aaa2223
m.start(1);  //返回0 返回第⼀组匹配到的⼦字符串在字符串中的索引号
m.start(2);  //返回3
现在我们使⽤⼀下稍微⾼级点的正则匹配操作,例如有⼀段⽂本,⾥⾯有很多数字,⽽且这些数字是分开的,我们现在要将⽂本中所有数字都取出来,利⽤java的正则操作是那么的简单.
Java代码⽰例:
Pattern p=Patternpile("\\d+");
Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa");
while(m.find()) {
System.out.up());
}
输出:
456456
0532214
123
如将以上while()循环替换成
while(m.find()) {
System.out.up());
System.out.print("start:"+m.start());
System.out.println(" end:"+m.end());
}
则输出:
456456
start:6 end:12
0532214
start:19 end:26
123
start:36 end:39
现在⼤家应该知道,每次执⾏匹配操作后start(),end(),group()三个⽅法的值都会改变,改变成匹配到的⼦字符串的信息,以及它们的重载⽅法,也会改变成相应的信息.
注意:只有当匹配操作成功,才可以使⽤start(),end(),group()三个⽅法,否则会抛出java.lang.IllegalStateException,也就是当
matches(),lookingAt(),find()其中任意⼀个⽅法返回true时,才可以使⽤.
转⾃

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。