今天学习到了正则表达式,不可避免的接触到了Pattern类与Matcher类,作为一个初学者来说,这让我突然跳脱出前段时间自己对构造方法和普通方法的理解,感觉到前所未有的迷惑。不过,通过各种途径的学习,终于能够顺利的形成自己的理解,并借此由正常的语言记录下来这些想法。
首先说Pattern类,要获得Pattern类的实例,并不能通它的过构造方法来创建,它的构造方法是私有的,所以是要用compile()方法来完成的。
看一下compile方法的定义:public static Pattern compile(String regex) 所以需要传入的就是字符串类型的正则表达式的规范,如"\\d+"等;返回的则是一个Pattern类的实例。
所以Pattern类的实例化Java代码示例:
String s="\\d+"; //定义替换规则
Pattern p=Pattern.compile(s); //Pattern类的实例化
实例化完成,可以用p.pattern();来检测是否建立成功,其中pattern() 返回正则表达式的字符串形式,其实就是返回上述定义中的regex参数。Pattern类实例p可以理解为一个规范,一种匹配条件, 那么这种规范的存在究竟有什么作用呢?在此就以Pattern类中的split()方法为例。Pattern.split()的定义是:public String[] split(CharSequence input),此方法的目的描述为字符串拆分,返回一个字符串组String[]。
Java代码示例:
Pattern p=Pattern.compile("\\d+"); //定义替换规则并实例化Pattern类
String s="我的身份证号是123456学号是0987准考证号是789";//定义一个输入字符序列
String str[]=p.split(s);//进行字符串拆分
最终的结果是得到一个字符串数组str[]={"我的身份证号是","学号是","准考证号是"},可以看出Pattern.split()的更为形象和容易理解的描述就是:以p中的替换规则作为规范,将传入的CharSequence字符序列进行拆分,遇到一次“\\d+”即数字出现一次或多次的情况时,就拆分一次直到该序列的结束。现在理解后想想,其实和开始学习数组时碰到的String.split(String regex)方法类似,对比现在学习到的Pattern.split(),更为形象的可以理解为一个是将拆分规范传入了方法中再作为属性来参与拆分,而Pattern类的出现则是将规范作为类,有了更为系统性的表示规则,但这并不影响我们对它的理解,在对Pattern.split()这种方法的调用时,它也就只是作为一个在方法实施的告诉我们以什么来拆分的要求或者说规范而已。
既然说了Pattern类的实例化方法,也以该类的基本方法说明了自己的理解方式,那接下来不得不提与之息息相关的Matcher类了。
就像前文所说的那样,其实Pattern类的实例化能够得到的是一个规范,一个方法运行的对比模板之类的,但真正想要得到将规范进行匹配操作的后的结果,还需要与Matcher一起合作。
Matcher类也与Pattern类的实例化一样,它的构造方法也是私有的,并不能通它的过构造方法来创建实例化对象。只能通过Pattern.matcher(CharSequence input)方法来得到该类的实例.
所以Matcher类的实例化Java代码示例:
<pre name="code" class="java">Pattern p=Pattern.compile("\\d+")//定义替换规则并实例化Pattern类
Matcher m=p.matcher("123a65479"); //获得Matcher类实例
学到此处我曾一度纠结这究竟是个什么玩意儿,用一个类中的方法实例化出的对象再调用类中的另一个方法就能实例化另一个类的对象,想了很久,终于想出了自己能理解的解释方法:那就是p给出的是一个规范,m给出的则是用这个规范进行匹配的这个基本操作,至于这基本操作的匹配结果或者在此基础上的不同的指定匹配方式的结果,可以调用Matcher类中的其他方法来实现。以最基本的matches()为例,其定义是public boolean matches(),作用是执行验证。
Java代码示例:
<pre name="code" class="java">Pattern p=Pattern.compile("\\d+")//定义替换规则并实例化Pattern类
Matcher m=p.matcher("123a65479"); //获得Matcher类实例
m.matches();//返回false,因为a不能被\d+匹配,所以整个字符串匹配失败.
<div>Matcher m1=p.matcher("123654");
</div><div>m1.matches();//返回true,因为\d+匹配到了整个字符串 </div>
所以说Pattern.matcher()得到的是一个匹配操作,产生将双方进行匹配的动作,但是这个匹配的执行及其结果则通过Matcher.matches()来完成。
Matcher类中不只有会返回是否匹配的方法,还有在匹配过程做出更多其他操作的方法,以replaceAl()l为例,其定义是public String replaceAll(String replacement),作用是字符串替换。
Java代码示例:
Pattern p=Pattern.compile("\\d+")//定义替换规则并实例化Pattern类
Matcher m=p.matcher("123a65479"); //获得Matcher类实例
String s=m.replaceAll("_"); //s返回_a_ 数字部分由于\d+的规范全部被替换成下划线_.
不过String类中也有对支持正则表达式的操作,这些方法的定义理解其实与上文相似:
public boolean matches(String regex)作用:字符串匹配;
public String[] split(String regex)作用:字符串拆分;
public StringreplaceAll(String regex,String replacement)作用:字符串替换;
有了这些方法,可以对上面的代码进行改进,也能达到相同的效果。
Java代码示例:
String str[]="我的身份证号是123456学号是0987准考证号是789".split("\\d+");//返回字符串数组,str[0]="我的身份证号是",str[1]="学号是",str[2]="准考证号是"
boolean temp="123a65479".matches("\\d+");//返回false,因为a不能被\d+匹配,所以整个字符串匹配失败.
boolean temp1="123a65479".matches("\\d{3}[a-z]\\d+");//返回true,字符串与规范的组合进行匹配,由于123被\d{3}匹配,a又和[a-z]匹配,65479也能和\d+匹配,所以整个字符串匹配成功.
String s="123a65479".replaceAll("\\d+","_");//s返回_a_
以上代码得到的结果与之前的一样,所以要用上文中的方法时,可以直接用String类中的方法,这样明显是比较方便的。不过有要求其他的String类中没有的正则操作的方法,还是要依靠Matcher类中的方法来实现。