Java Matcher类详解

Matcher对象是一个状态机器,它依据Pattern对象做为匹配模式对字符串展开匹配检查,此类的实例用于多个并发线程是不安全的。

定义

public final class Matcher extends Object implements MatchResult

构造器

Matcher(Pattern parent, CharSequence text) {
    this.parentPattern = parent;
    this.text = text;

    // Allocate state storage
    int parentGroupCount = Math.max(parent.capturingGroupCount, 10);
    groups = new int[parentGroupCount * 2];
    locals = new int[parent.localCount];

    // Put fields into initial states
    reset();
}

Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例. 

获取Matcher实例

Pattern p=Pattern.compile("\\d+"); 
Matcher m=p.matcher("22bb23"); 
m.pattern();//返回p 也就是返回该Matcher对象是由哪个Pattern对象的创建的 

方法

String toString()

Pattern p = Pattern.compile("(\\w+)%(\\d+)");
Matcher m = p.matcher("ab%12-cd%34");
System.out.println(m.toString());

执行结果:

java.util.regex.Matcher[pattern=(\w+)%(\d+) region=0,11 lastmatch=]

Matcher reset()

Pattern p = Pattern.compile("(\\w+)%(\\d+)");
Matcher m = p.matcher("ab%12-cd%34");
if (m.find()) {
    System.out.println("开始索引:" + m.start()); // 开始索引:0
    System.out.println("group():" + m.group()); // group():ab%12
}
if (m.find()) {
    System.out.println("开始索引:" + m.start()); // 开始索引:6
    System.out.println("group():" + m.group()); // group():cd%34
}

reset()方法改变了变量first 、last 、oldLast、lastAppendPosition、from、to的值并将数组groups、locals初始化。


状态变化:

变量 类型 新值
first  int  -1
last  int  0
oldLast int  -1
lastAppendPosition int  0
from int  0
to int
text.length()
groups
int[]
locals[i] = -1
locals
int[]
 
locals[i] = -1

Matcher reset(CharSequence input)

Pattern p = Pattern.compile("(\\w+)%(\\d+)");
Matcher m = p.matcher("ab%12-cd%34");
m.reset("ef%56-gh%78");
while (m.find()) {
    System.out.println("group():" + m.group());
}

运行结果:

group():ef%56
group():gh%78

Pattern pattern()

pattern()返回parentPattern,返回由此匹配器解释的模式,即构造器传入的Pattern对象。

int groupCount()

返回此匹配器模式中的捕获组数。根据惯例,零组表示整个模式。

Pattern p = Pattern.compile("(\\w+)%(\\d+)");
Matcher m = p.matcher("ab%12-cd%34");
System.out.println(m.groupCount());// 2

String group()

返回当前查找而获得的与组匹配的所有子串内容。group()实际调用了group(int group)方法,参数group为0。组零表示整个模式。

String group(int group)

返回当前查找而获得的与组匹配的所有子串内容。

int start()

返回当前匹配的子串的第一个字符在目标字符串中的索引位置 。start()方法返回的是匹配器的状态first。

int start(int group)

返回当前匹配的指定组中的子串的第一个字符在目标字符串中的索引位置 。

int end()

返回当前匹配的子串的最后一个字符的下一个位置在目标字符串中的索引位置 。end()方法返回的是匹配器的状态last。

int end(int group)

返回当前匹配的的指定组中的子串的最后一个字符的下一个位置在目标字符串中的索引位置 。

boolean find()

在目标字符串里查找下一个匹配子串。如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。 

boolean find(int start)

重置此匹配器,然后尝试查找匹配该模式,从指定的位置开始查找下一个匹配的子串。如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。

int regionStart()

报告此匹配器区域的开始索引。end()方法返回的是匹配器的状态from。

int regionEnd()

报告此匹配器区域的结束索引(不包括)。end()方法返回的是匹配器的状态to。

Matcher region(int start,int end)

设置此匹配器的区域限制。重置匹配器,然后设置区域,使其从 start 参数指定的索引开始,到 end 参数指定的索引结束(不包括end索引处的字符)。 

boolean lookingAt()

从目标字符串开始位置进行匹配。只有在有匹配且匹配的某一子串中包含目标字符串第一个字符的情况下才会返回true。

boolean matches()

只有完全匹配时才会返回true。

Matcher appendReplacement(StringBuffer sb, String replacement) 

将当前匹配子串替换为指定字符串,并将从上次匹配结束后到本次匹配结束后之间的字符串添加到一个StringBuffer对象中,最后返回其字符串表示形式。

StringBuffer appendTail(StringBuffer sb)

将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。 

String replaceAll(String replacement)

将匹配的子串用指定的字符串替换。

String replaceFirst(String replacement)

将匹配的第一个子串用指定的字符串替换。

Matcher usePattern(Pattern newPattern)

更改匹配器的匹配模式。 

public static void main(String[] args) {
    Pattern p = Pattern.compile("[a-z]+");
    Matcher m = p.matcher("111aaa222");
    System.out.println(piPei(m)); // (模式[a-z]+):匹配子串:aaa;开始位置:3;结束位置:6;
    m.usePattern(Pattern.compile("\\d+"));
    System.out.println(piPei(m)); // (模式\d+):匹配子串:222;开始位置:6;结束位置:9;
}

public static String piPei(Matcher m) {
    StringBuffer s = new StringBuffer();
    while (m.find()) {
        s.append("匹配子串:" + m.group() + ";");
        s.append("开始位置:" + m.start() + ";");
        s.append("结束位置:" + m.end() + ";");
    }
    if (s.length() == 0) {
        s.append("没有匹配到!");
    }
    s.insert(0, "(模式" + m.pattern().pattern() + "):");
    return s.toString();
}
Pattern p = Pattern.compile("[a-z]+");
Matcher m = p.matcher("111aaa222");
System.out.println(piPei(m));// (模式[a-z]+):匹配子串:aaa;开始位置:3;结束位置:6;
m.usePattern(Pattern.compile("\\d+"));
m.reset();
System.out.println(piPei(m));// (模式\d+):匹配子串:111;开始位置:0;结束位置:3;匹配子串:222;开始位置:6;结束位置:9;

例子

public class MatcherTest {
    public static void main(String[] args) throws Exception {
        //生成Pattern对象并且编译一个简单的正则表达式"Kelvin" 
        Pattern p = Pattern.compile("Kevin");
        //用Pattern类的matcher()方法生成一个Matcher对象 
        Matcher m = p.matcher("Kelvin Li and Kelvin Chan are both working in Kelvin Chen's KelvinSoftShop company");
        StringBuffer sb = new StringBuffer();
        int i = 0;
        //使用find()方法查找第一个匹配的对象 
        boolean result = m.find();
        //使用循环将句子里所有的kelvin找出并替换再将内容加到sb里 
        while (result) {
            i++;
            m.appendReplacement(sb, "Kevin");
            System.out.println("第" + i + "次匹配后sb的内容是:" + sb);
            //继续查找下一个匹配对象 
            result = m.find();
        }
        //最后调用appendTail()方法将最后一次匹配后的剩余字符串加到sb里; 
        m.appendTail(sb);
        System.out.println("调用m.appendTail(sb)后sb的最终内容是:" + sb.toString());
    }
}

输出结果:

第1次匹配后sb的内容是:Kevin 
第2次匹配后sb的内容是:Kevin Li and Kevin 
第3次匹配后sb的内容是:Kevin Li and Kevin Chan are both working in Kevin 
第4次匹配后sb的内容是:Kevin Li and Kevin Chan are both working in Kevin Chen's Kevin 
调用m.appendTail(sb)后sb的最终内容是:Kevin Li and Kevin Chan are both working in Kevin Chen's KevinSoftShop company. 

总结

1. Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例. 
2. 一个Matcher实例是被用来对目标字符串进行基于既有模式(也就是一个给定的Pattern所编译的正则表达式)进行匹配查找的,所有往Matcher的输入都是通过CharSequence接口提供的,这样做的目的在于可以支持对从多元化的数据源所提供的数据进行匹配工作。