一开始学习Java正则表达式,总会错误的API当成理所当然的来使用,结果得来的就是花更多的时间工作。今天就遇到了,正则表达式里的Matcher类的groupCount。
首先看看,Java如何创建正则表达式:
Pattern p=Pattern.compile("([a-z]+)(\\d+)([a-z]+)(\\d)");
Matcher m=p.matcher("aaa2223bb");
分组 API : Mathcer.start(int)/ Matcher.end(int) / Matcher.group(int) /Matcher.groupCount()
for(int i = 0 ; i < m.groupCount ; i ++){
m.start(i);
m.end(i);
m.group(i);
}
看起来这组API就是获取匹配的结果串了,实际不是,他是获取正则表达式子模式的匹配串,也就是在目标字符串中匹配有多少满足子模式匹配条件的字符串,所谓子模式通俗点说就是小括号里的内容了,所以这种API不是我们想要的结果,尤其是groupCount,他不是最终匹配的结果数,他只是子模式匹配的结果数,一般情况下子模式有几个,他就是几。
结果API: Mathcer.start()/ Matcher.end() / Matcher.group() /Mathcer.find()
while(m.find()){
m.start();
m.end();
m.group();
}
这组API才是正确获取匹配结果的方法,类似于JDBC的ResultSet,所以使用之前一定要判断find。
正则表达式的贪婪模式
非贪婪模式是指尽可能少的查找满足匹配的结果,一般情况下我们使用都是非贪婪模式。使用贪婪模式的话,需要加上(*?);这个就是贪婪模式的开始。比如下面的匹配:
String pattern = "<a>(.*)</a>"; 非贪婪
String target = "<a>hello<a>world</a>welcome</a>";
结果就是:<a>hello<a>world</a>welcome</a>
String pattern = "<a>(.*?)</a>"; 贪婪
String target = "<a>hello<a>world</a>welcome</a>";
结果就是:<a>hello<a> 和 </a>welcome</a>
正则表达式子模式
正则表达式中经常有括号,包括小括号,大括号,中括号。他们分别代表不同的意义,关键是小括号,它代表的是一个子模式。类似于pattern中又有pattern,所以对于一些复杂的pattern,我们都是使用小括号来包装子模式的,然而子模式不是必须的,只是,子模式可以突出pattern的重点。另外模式匹配的顺序是按照pattern的书写顺序,没有明确的API规定谁前谁后,除了一行的首末位。