正则find与matches

前言

今天帮同事写正则,突然发现matcher里的find与matches方法开始并不能讲清区别,记录下

正文

find()与matches()的区别:

find():是否存在与该模式匹配的下一个子序列。简单来说就是在字符某部分匹配上模式就会返回true,同时匹配位置会记录到当前位置,再次调用时从该处匹配下一个。

matches():整个字符串是否匹配上模式,匹配上则返回true,否则false。

需要注意的是:

  1. 如果先调用 matches(),再调用find(),会导致find匹配不成功;
    反之,先调用find(),再调用matches()不会影响。(原因在下面会分析)
    可以使用find的带参数的方法,传入0即可,find(0)。
  2. 如果没有匹配上,调用start()时会抛错。

原因

find方法会去找上一次匹配后的标识符,然后去匹配,
matches直接使用传入字符的起始位置,并会在匹配结束成功后将匹配标识符置到最后。
可以看下源码,如下

	//Matcher 类
	/**
     * The range within the sequence that is to be matched. Anchors
     * will match at these "hard" boundaries. Changing the region
     * changes these values.
     */
	//这个是字符的起始和结束
    int from, to;
    /**
     * The range of string that last matched the pattern. If the last
     * match failed then first is -1; last initially holds 0 then it
     * holds the index of the end of the last match (which is where the
     * next search starts).
     */
	//这个就是上一次匹配的范围,注意调用start()时如果first为-1会向外抛错
    int first = -1, last = 0;

    /**
     * The end index of what matched in the last match operation.
     */
    int oldLast = -1;
	
	//初始化matcher时会调用这个方法,from,to赋值
	public Matcher reset() {
        first = -1;
        last = 0;
        oldLast = -1;
        for(int i=0; i<groups.length; i++)
            groups[i] = -1;
        for(int i=0; i<locals.length; i++)
            locals[i] = -1;
        lastAppendPosition = 0;
        from = 0;
        to = getTextLength();
        return this;
    }
	
	//matches使用的是from,并会在结束后,将标识符置到末尾
	public boolean matches() {
        return match(from, ENDANCHOR);
    }
	boolean match(int from, int anchor) {
        this.hitEnd = false;
        this.requireEnd = false;
        from        = from < 0 ? 0 : from;
        this.first  = from;
        this.oldLast = oldLast < 0 ? from : oldLast;
        for (int i = 0; i < groups.length; i++)
            groups[i] = -1;
        acceptMode = anchor;
        boolean result = parentPattern.matchRoot.match(this, from, text);
        if (!result)
            this.first = -1;
        this.oldLast = this.last;
        return result;
    }
	
	//find是直接使用的之前的last,所以如果在matches匹配成功后,再用find就不行了。当然可以使用find(0)
	 public boolean find() {
        int nextSearchIndex = last;
        if (nextSearchIndex == first)
            nextSearchIndex++;

        // If next search starts before region, start it at region
        if (nextSearchIndex < from)
            nextSearchIndex = from;

        // If next search starts beyond region then it fails
        if (nextSearchIndex > to) {
            for (int i = 0; i < groups.length; i++)
                groups[i] = -1;
            return false;
        }
        return search(nextSearchIndex);
    }
原文地址:https://www.cnblogs.com/wmg92/p/13749433.html