正则表达式在匹配字符串的过程中应用广泛,如果能够熟练掌握正则表达式,在学习工作中解决字符串相关问题可以事半功倍。
java.util.regex 包下的Pattern和Matcher类提供了Java中正则表达式的解决方案。
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b"); //编译"a*b"为Pattern类的实例
Matcher m = p.matcher("aaaaab"); //该实例与"aaaaab"匹配
boolean b = m.matches(); //对是否匹配返回一个布尔值
--【出自JDK1.6文档】
场景分析:有一个字符串>>>"rows=[Rowcolumns=[1, c], Rowcolumns=[2, java], Rowcolumns=[3, ruby], Rowcolumns=[4, go], Rowcolumns=[5, python], Rowcolumns=[6, lua], Rowcolumns=[7, csharp], Rowcolumns=[8, ajax], Rowcolumns=[9, jsp]]";"
现在要截取[ ]中的数据,即1,c/2,java/3,ruby...
那么根据上述的套路,首先我们要写出一个正则并将其编译为Pattern类的实例,因为上述字符串中[ ]有两种形态,一种是"rows=[",另一种是"Rowcolumes=[",我们只想匹配后面的这种子串,所以
1.直接选取“ns=[”作为开头,先写出这个子串的表达式“ns”是具体的字母,不用改变,"="和"["都是特殊字符,需要进行转义,因此“ns=[”的正则表达式为"ns\\=\\[",同理结尾匹配"\\]"
2.这样已经匹配了开头,但我们想截取的字符串并不想带上开头和结尾,因此需要运用零宽断言,举例来说(?=exp)代表匹配以exp结尾的字符串,但匹配出来的结果并不带exp,例如(?=ing)匹配reading,结果为read;(?<=exp)匹配以exp开头的字符串,但结果不带exp,例如(?<=read)匹配reading,结果为ing。这样一来我们的问题都解决了,运用零宽断言,开头匹配"(?<=ns\\=\\[)",结尾匹配"(?=\\])"
3.开头和结尾都搞定了,还差中间,我们队中间的数据没有要求,因此直接匹配".*"(任意字符匹配0次或多次),但是这里有一个问题是,这个表达式是贪心的,因此它会匹配完整个字符串,即"(?<=ns\\=\\[).*(?=\\])"匹配的结果是"2, java], Rowcolumns=[3, ruby], Rowcolumns=[4, go], Rowcolumns=[5, python], Rowcolumns=[6, lua], Rowcolumns=[7, csharp], Rowcolumns=[8, ajax], Rowcolumns=[9, jsp",显然不是我们想要的,因此再添加一个"?"(前面的内容匹配0次或1次)
4.最后需要截取的子串的正则表达式就是"(?<=ns\\=\\[).*?(?=\\])"
5.在Java中使用处理字符串
Pattern pattern = Pattern.compile("(?<=ns\\=\\[).*?(?=\\])");
Matcher matcher = pattern2.matcher(string);
while(matcher.find()){
System.out.println(matcher.group());
}
其中有一个String group()方法,它返回匹配到的字符串,在上述例子中的正则表达式只有一个group,所以直接调用group()方法就行。如果一个正则表达式形如"((//d+,)(//d+))"那么他就有三个group,分别匹配从左到右的第n个左括号里的正则表达式。group()与group(0)等价,匹配整个正则表达式;gruop(1)匹配"(//d+,)(//d+)";group(2)匹配"//d+,";group(3)匹配"//d+,"。编译执行以上代码就可以得到我们想要的结果。
参考: