12、正则表达式中的Matcher类总结

正则表达式不多介绍,记住要

import java.util.regex.*;

主要总结一下Pattern和Matcher的一些东西。

先看代码:

public class RegExPrac {public static void main(String[] args){String str = "1588344570615883445706";Matcher m = Pattern.compile("(((13\\d)|(15\\d))\\d{8})+?").matcher(str);while(m.find()){System.out.println("start at : " + m.start() + ";end at :"+ m.end(1) + " output : " + m.group());}}}Pattern.compile是一个类方法,查阅API文档可知,compile有两种重载,一种是compile(String regex),另一种多一个参数compile(String regex, int flags),flags是一个用以约束的描述符,有一些宏与其对应。compile返回一个 Pattern对象,Pattern没有可见的构造器。Pattern有一些方法,不过不是重点,Pattern对象保存着compile的参数,可以产生Matcher对象,Matcher对象是重点。

Matcher的构造器也是不可见的,只能通过Pattern对象的matcher(String str)方法产生Matcher实例,Pattern为什么可以调用Matcher的构造器?我表示疑惑,有空研究一下源码。

关于Matcher归类简介几点:

1、匹配。

匹配主要有find()、lookingAt()和matches(),它们都返回一个boolean值,表示是否找到了匹配的结果

find():文档中这样说:Attempts to find the next subsequence of the input sequence that matches the pattern. 即是在输入的序列中去找“下一个”匹配模版的子序列。这里的“找”如果找到了,则把结果存在某处,返回一个true,用group()方法就可以把这个已经存好的结果输出。find()从头到位把序列检查一遍之后就不再检查,之后会一直输出false。使用find(int start)可以设定一个起始位置重新开始查找。

比如最上方的代码,((13\\d)|(15\\d))\\d{8} 表示“13x开头,或者15x开头,后面有八个x” x代表数字。其实也可以写成((13)|(15))\\d{9}。把这个式子括起来,加上数量表示符“+?”。加号表示的条件是:前面的式子出现一次或者多次。问号表示“勉强模式”:匹配最少的字符。所以这个条件就是寻找模版只出现一次的情况。

第一次调用find(),找到前11位,m.group()输出一个String结果。再次调用find(),找到后11位,group()又输出一个结果。此时已经到了字符串的结尾,第三次调用find()将返回false,循环结束。

所以程序的结果是:

start at : 0;end at :11 output : 15883445706start at : 11;end at :22 output : 15883445706

lookingAt():

这个方法只查找字符串的开头,开头能够匹配则返回true,否则返回false。所以如果在上述程序中使用

while(m.lookingAt()){System.out.println("start at : " + m.start() + ";end at :"+ m.end(1) + " output : " + m.group());}就会一直循环下去,检查开头—-匹配—–输出—–检查开头—–匹配—–输出……

matches():

这个方法检查整个字符串,把程序修改如下

import java.util.regex.*;public class RegExPrac {public static void main(String[] args){String str = "1588344570615883445706";Matcher m = Pattern.compile("(((13)|(15))\\d{9})+").matcher(str);while(m.find()){System.out.println("start at : " + m.start() + ";end at :"+ m.end(1) + " output : " + m.group());}}}可以看到,正则表达式尾部的数量表示符只有一个“+”,表示此式子出现一次或者多次,加号之后没有其他限定,默认采用“贪婪模式”,即允许的范围内尽量多,所以会匹配“多次”,而“多次”这个概念没有上限,所以会匹配到无法匹配为止。

所以结果是,一次性把两个相连的电话号码都匹配了,输出:

start at : 0;end at :22 output : 1588344570615883445706

2、Matcher每次查找匹配之后的定位行为:

find()的行为,以以下代码为例:

import java.util.regex.*;public class RegExPrac {public static void main(String[] args){String str = "1588344570615883d445706";Matcher m = Pattern.compile("(((13)|(15))\\d{9})?").matcher(str);//零次或一次,贪婪模式//System.out.println(m.groupCount());//m.matches();//System.out.println(m.start(0));//System.out.println(m.start(1));//System.out.println(m.start(2));//System.out.println(m.start(3));//m.lookingAt();while(m.find()){System.out.println("start at : " + m.start() + ";end at :"+ m.end(1) + " output : " + m.group());}}}结果是:

start at : 0;end at :11 output : 15883445706start at : 11;end at :-1 output :start at : 12;end at :-1 output :start at : 13;end at :-1 output :start at : 14;end at :-1 output :start at : 15;end at :-1 output :start at : 16;end at :-1 output :start at : 17;end at :-1 output :start at : 18;end at :-1 output :start at : 19;end at :-1 output :start at : 20;end at :-1 output :start at : 21;end at :-1 output :start at : 22;end at :-1 output :start at : 23;end at :-1 output :

可以发现,匹配到第一个正确的号码后,没有再找到能够匹配“一次”的结果,于是回到上一次的结果的后一个字符,开始匹配“零次”。

lookingAt的行为,以以下代码为例:

import java.util.regex.*;public class RegExPrac {public static void main(String[] args){String str = "158d8344570615883445706";Matcher m = Pattern.compile("(((13)|(15))\\d{9})?").matcher(str);//System.out.println(m.groupCount());//m.matches();//System.out.println(m.start(0));//System.out.println(m.start(1));//System.out.println(m.start(2));//System.out.println(m.start(3));m.lookingAt();while(m.find()){System.out.println("start at : " + m.start() + ";end at :"+ m.end(1) + " output : " + m.group());}}}结果是:一定要成为你工作最大的资产。

12、正则表达式中的Matcher类总结

相关文章:

你感兴趣的文章:

标签云: