Pattern 和 Matcher

  • Pattern和Matcher
  • Pattern
  • **Pattern的创建**
  • **split方法**
  • **全局匹配**
  • Matcher
  • **Matcher类的创建**
  • **全局匹配**
  • **find方法**
  • **lookingAt方法**
  • **start方法**
  • **end方法**
  • **group方法**
  • **region方法**
  • **reset方法**
  • **替换方法**
  • **appendReplacement和appendTail**


Pattern和Matcher

 今天又复习了以下java的基础知识,发现对Pattern和Matcher的使用又生疏了,特地整理了一下,Pattern可以看作是一个正则表达式的匹配模式,Matcher可以看作是管理匹配结果,重复使用正则表达式匹配的一个类。

Pattern

Pattern的创建

//pattern创建一个正则匹配
        Pattern pattern = Pattern.compile("java");
        System.out.println(pattern);//java

split方法

 方法中第二个参数是可选参数,代表limit,也就是切分结果的个数限制。

String[] split = pattern.split("123123java123123",4);//通过正则匹配切分
        for(String s : split){//123123 123123
            System.out.println(s);
        }

全局匹配

 Pattern带有一个静态方法用于对字符串进行全局匹配。第一个参数是正则表达式,后一个参数是被匹配字符串。

//自带一个matcher方法,但是只能做全局匹配
        System.out.println(Pattern.matches("java","java"));//true

Matcher

 但需要匹配的要求变得复杂,我们就需要使用到Matcher类了,该类一般和Pattern一起使用。

Matcher类的创建

 必须提供一个参数,该参数代表被匹配的字符串,由于matcher通过pattern.matcher()方法生成,当中已经存储了正则表达式和目标字符串。

/*matcher提供了一个匹配类,可以多次使用正则式,用于提供各种匹配和管理匹配内容,matcher得到了pattern的正则表达式和需要匹配的字符串。
         */
        String s = "123java123";
        Matcher matcher = pattern.matcher(s);//java.util.regex.Matcher[pattern=java region=0,9 lastmatch=]

全局匹配

System.out.println(matcher.matches());//false

find方法

 find方法需要好好讲一下,find方法顾名思义,就是查找,如果不传入参数,那么find会从索引0开始查找,一旦找到匹配的字符串就会返回true。
 需要注意的是,find是不断向后查找的,什么意思呢,就是说你第一次调用find,查找到的是第一个匹配的子字符串,假如目标字符串有多个匹配项,那么再调用一次,查找到的就是第二个匹配的字符串,matcher会记录好相应的匹配信息。
 如果传入一个参数x,代表find从索引x开始查找

//可以从任意位置查找,只要子字符串找到返回true 注意:每次调用find都会往后查找一次。
 		Pattern pattern = Pattern.compile("java");
 		String s = "123java123";
        Matcher matcher = pattern.matcher(s);
        System.out.println(matcher.find());//true
        System.out.println(matcher.find(3));//true
        System.out.println(matcher.find(2));//true
        System.out.println(matcher.find(6));//false

lookingAt方法

 从索引0开始匹配,如果匹配上了返回true,不需要全局匹配。与find不同,lookingAt要求第一个字符开始就要匹配,否则返回false

//从第一个开始匹配,能匹配上就返回true,不需要全局匹配
    Pattern pattern = Pattern.compile("java");
 	String s = "123java123";
    Matcher matcher = pattern.matcher(s);
    System.out.println(matcher.lookingAt());//false
    String s1 = "java123";
    matcher = pattern.matcher(s1);
    System.out.println(matcher.lookingAt());//true

start方法

//start()返回匹配字符串开始位置
        System.out.println(matcher.start());

end方法

//end()返回匹配字符串结束位置
        System.out.println(matcher.end());

group方法

 group的概念是相对正则匹配式的,比如正则匹配式(java)(python)©就是包含了3个group,注意group(0)为javapythonc。

Pattern pattern = Pattern.compile("java");
 	String s = "123java123";
    Matcher matcher = pattern.matcher(s);
    System.out.println(matcher.group());//java
    pattern = Pattern.compile("(java)(python)(c)");
    //注意:虽然分组了,但匹配时还是要将javapythonc都匹配上,否则报错。
    String s2 = "123javapythonc342c34546";
    matcher = pattern.matcher(s2);
    //要使用start,end,group等方法,要先进行一次匹配,这样才有记录,不然会报错
    matcher.find();

    System.out.println(matcher.groupCount());//3

    //没参数默认group(0);也就是整个正则表达式
    System.out.println(matcher.start());//3
    System.out.println(matcher.end());//14
    System.out.println(matcher.group());//javapythonc
    System.out.println(matcher.start(1));//3
    System.out.println(matcher.end(1));//7
    System.out.println(matcher.group(1));//java
    System.out.println(matcher.start(2));//7
    System.out.println(matcher.end(2));//13
    System.out.println(matcher.group(2));//python
    System.out.println(matcher.start(3));//13
    System.out.println(matcher.end(3));//14
    System.out.println(matcher.group(3));//c

注意
在使用start,end,group方法之前都需要调用find方法,确保matcher进行了一次查询并记录后才能调用之前的方法,否则报错,同时如果find没有找到匹配的子字符串,会报错no matcher find。

region方法

/*
        region用于设定查找范围,设定之后之前查找保存在mathcer中的结果清空
         */
        matcher.region(1,15);
        System.out.println(matcher.regionStart());//1
        System.out.println(matcher.regionEnd());//15
        matcher.find();
        System.out.println(matcher.group());//javapythonc

reset方法

pattern = Pattern.compile("(java)(python)(c)");
    String s2 = "123javapythonc342c34546";
    matcher = pattern.matcher(s2);
//重置匹配器方法
        matcher.reset();//重置后调用find会从0索引开始查找
//        System.out.println(matcher.group());//出错,因为已经重置,matcher里没有匹配记录。
        matcher.reset("javapythonc123javapythonc");//重置需要匹配的字符串
        System.out.println(matcher.find());//true

替换方法

//替换方法
 //替换所有符合正则表达式的字符串       
 System.out.println(matcher.replaceAll("abc"));//abc123abc
//替换第一个匹配上的字符串        
System.out.println(matcher.replaceFirst("abc"));//abc123javapythonc

appendReplacement和appendTail

 这两个方法是比较复杂的,简单来说

  • appendReplacement是将这次查找匹配到的字符串及其之前的字符渐进地输出到一个StringBuffer中去。
  • appendTail是将剩下的为匹配的字符串输出到一个StringBuffer中。
@Test
    public void appendTest(){
        Pattern pattern = Pattern.compile("a|b");
        Matcher matcher = pattern.matcher("abcabca@126.com");
        StringBuffer sb = new StringBuffer();
        StringBuffer sb1 = new StringBuffer();
        while(matcher.find()){//每次find向后查找一个匹配项
            matcher.appendReplacement(sb, matcher.group().toUpperCase());
            System.out.println(sb);
        }
        matcher.appendTail(sb1);
        System.out.println(sb1);
    }

输出结果如下:

A
AB
ABcA
ABcAB
ABcABcA
@126.com