Matcher中appendReplacement()方法与replaceAll()方法的联系

来源:互联网 发布:文怡 淘宝 编辑:程序博客网 时间:2024/05/16 02:03

先看这段代码

package com.mjlf.myBatis.accessControl.regex;import java.util.regex.Matcher;import java.util.regex.Pattern;/** * Created by a123 on 16/12/27. */public class Test {    public static void main(String[] args){        Pattern p = Pattern.compile("java");        Matcher m = p.matcher("The java book is java program book c");        StringBuffer sb = new StringBuffer();        if(m.find()){            m.appendReplacement(sb,"python");        }        System.out.println(sb);        if(m.find()){            m.appendReplacement(sb,"python");        }        System.out.println(sb);        if(m.find()){            m.appendReplacement(sb,"python");        }        System.out.println(sb);        System.out.println(m.replaceAll("c++"));    }}/**The pythonThe python book is pythonThe python book is pythonThe c++ book is c++ program book c*/

看这段程序和对应输出可知,appendReplacement(StringBuffer sb, String replaceMent)方法是将输入字符序列首次与正在表达式匹配的部分进行更改为replaceMent并且把结果添加到一个sb结果集中,对于匹配之前的字符序列,它们被转移到sb字符集中。

如果输入字符集中没有能与正则表达式匹配的, 则appendReplacement(StringBuffer sb, String replaceMent)方法的sb参数将没有任何变化。

replaceAll(String replaceMent)则是将输入字符序列中所有能与正则表达式匹配的字符集与replaceMent进行更改, 最后将更换后的字符序列返回。

看如下是这两个方法的源码,可看到在replaceAll()是采用appendReplacement()方法实现更改的。

replaceAll(String replacement)方法

public String replaceAll(String replacement) {        reset();        boolean result = find();        if (result) {            StringBuffer sb = new StringBuffer();            do {                appendReplacement(sb, replacement);                result = find();            } while (result);            appendTail(sb);            return sb.toString();        }        return text.toString();    }

appendReplacement(StringBuffer sb, String replacement)方法

public Matcher appendReplacement(StringBuffer sb, String replacement) {        // If no match, return error        if (first < 0)            throw new IllegalStateException("No match available");        // Process substitution string to replace group references with groups        int cursor = 0;        StringBuilder result = new StringBuilder();        while (cursor < replacement.length()) {            char nextChar = replacement.charAt(cursor);            if (nextChar == '\\') {                cursor++;                if (cursor == replacement.length())                    throw new IllegalArgumentException(                        "character to be escaped is missing");                nextChar = replacement.charAt(cursor);                result.append(nextChar);                cursor++;            } else if (nextChar == '$') {                // Skip past $                cursor++;                // Throw IAE if this "$" is the last character in replacement                if (cursor == replacement.length())                   throw new IllegalArgumentException(                        "Illegal group reference: group index is missing");                nextChar = replacement.charAt(cursor);                int refNum = -1;                if (nextChar == '{') {                    cursor++;                    StringBuilder gsb = new StringBuilder();                    while (cursor < replacement.length()) {                        nextChar = replacement.charAt(cursor);                        if (ASCII.isLower(nextChar) ||                            ASCII.isUpper(nextChar) ||                            ASCII.isDigit(nextChar)) {                            gsb.append(nextChar);                            cursor++;                        } else {                            break;                        }                    }                    if (gsb.length() == 0)                        throw new IllegalArgumentException(                            "named capturing group has 0 length name");                    if (nextChar != '}')                        throw new IllegalArgumentException(                            "named capturing group is missing trailing '}'");                    String gname = gsb.toString();                    if (ASCII.isDigit(gname.charAt(0)))                        throw new IllegalArgumentException(                            "capturing group name {" + gname +                            "} starts with digit character");                    if (!parentPattern.namedGroups().containsKey(gname))                        throw new IllegalArgumentException(                            "No group with name {" + gname + "}");                    refNum = parentPattern.namedGroups().get(gname);                    cursor++;                } else {                    // The first number is always a group                    refNum = (int)nextChar - '0';                    if ((refNum < 0)||(refNum > 9))                        throw new IllegalArgumentException(                            "Illegal group reference");                    cursor++;                    // Capture the largest legal group string                    boolean done = false;                    while (!done) {                        if (cursor >= replacement.length()) {                            break;                        }                        int nextDigit = replacement.charAt(cursor) - '0';                        if ((nextDigit < 0)||(nextDigit > 9)) { // not a number                            break;                        }                        int newRefNum = (refNum * 10) + nextDigit;                        if (groupCount() < newRefNum) {                            done = true;                        } else {                            refNum = newRefNum;                            cursor++;                        }                    }                }                // Append group                if (start(refNum) != -1 && end(refNum) != -1)                    result.append(text, start(refNum), end(refNum));            } else {                result.append(nextChar);                cursor++;            }        }        // Append the intervening text        sb.append(text, lastAppendPosition, first);        // Append the match substitution        sb.append(result);        lastAppendPosition = last;        return this;    }

下边是Oracle对appendRepalcement,replaceAll的描述

public Matcher appendReplacement(StringBuffer sb,
String replacement)
Implements a non-terminal append-and-replace step.
This method performs the following actions:

It reads characters from the input sequence, starting at the append position, and appends them to the given string buffer. It stops after reading the last character preceding the previous match, that is, the character at index start() - 1.

It appends the given replacement string to the string buffer.

It sets the append position of this matcher to the index of the last character matched, plus one, that is, to end().

The replacement string may contain references to subsequences captured during the previous match: Each occurrence of nameorg will be replaced by the result of evaluating the corresponding group(name) or group(g) respectively. For g,thefirstnumberafterthe is always treated as part of the group reference. Subsequent numbers are incorporated into g if they would form a legal group reference. Only the numerals ‘0’ through ‘9’ are considered as potential components of the group reference. If the second group matched the string “foo”, for example, then passing the replacement string “2bar"wouldcause"foobar"tobeappendedtothestringbuffer.Adollarsign() may be included as a literal in the replacement string by preceding it with a backslash ($).

Note that backslashes () and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are used to escape literal characters in the replacement string.

This method is intended to be used in a loop together with the appendTail and find methods. The following code, for example, writes one dog two dogs in the yard to the standard-output stream:

Pattern p = Pattern.compile(“cat”);
Matcher m = p.matcher(“one cat two cats in the yard”);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, “dog”);
}
m.appendTail(sb);
System.out.println(sb.toString());

Parameters:
sb - The target string buffer
replacement - The replacement string
Returns:
This matcher
Throws:
IllegalStateException - If no match has yet been attempted, or if the previous match operation failed
IllegalArgumentException - If the replacement string refers to a named-capturing group that does not exist in the pattern
IndexOutOfBoundsException - If the replacement string refers to a capturing group that does not exist in the pattern
appendTail

repalceAll方法描述

public String replaceAll(String replacement)
Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.
This method first resets this matcher. It then scans the input sequence looking for matches of the pattern. Characters that are not part of any match are appended directly to the result string; each match is replaced in the result by the replacement string. The replacement string may contain references to captured subsequences as in the appendReplacement method.

Note that backslashes () and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are >used to escape literal characters in the replacement string.

Given the regular expression a*b, the input “aabfooaabfooabfoob”, and the replacement string “-“, an invocation of this method on a matcher for that expression would yield the string “-foo-foo-foo-“.

Invoking this method changes this matcher’s state. If the matcher is to be used in further matching operations then it should first be reset.

Parameters:
replacement - The replacement string
Returns:
The string constructed by replacing each matching subsequence by the replacement string, substituting captured subsequences as needed

0 0
原创粉丝点击