You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从正则表达式替换中获取每个单独的替换结果?

如何从正则表达式替换中获取每个单独的替换结果?

核心问题

我们可以用matcher.group()获取当前正则匹配到的内容,但有没有类似方法能直接拿到当前替换后的结果字符串?

Java 实现方案

Java标准库的Matcher类并没有直接提供获取单次替换结果的API,但可以通过以下几种可靠的变通方式实现:

方法1:记录StringBuilder长度差(最简便可靠)

在调用appendReplacement前后分别记录StringBuilder的长度,差值部分就是本次替换的结果:

public class Test {
  public static void main(String[] args) {
    String content_SearchOn = "Sample sentence: snake, snail, snow, spider";
    String regexStrSubstitution = "$2$3$1";
    String regexStrMatchFor = "(s)(.)(.)";

    Matcher matcher = Pattern.compile(regexStrMatchFor).matcher(content_SearchOn);

    ArrayList<String> arr_regexMatchedWord = new ArrayList<>();
    ArrayList<String> arr_regexMatchedSubstitution = new ArrayList<>();

    StringBuilder sb_content_Replaced = new StringBuilder();
    while (matcher.find()) {
      String regexMatchedWord = matcher.group();
      arr_regexMatchedWord.add(regexMatchedWord);

      int beforeLength = sb_content_Replaced.length();
      matcher.appendReplacement(sb_content_Replaced, regexStrSubstitution);
      int afterLength = sb_content_Replaced.length();
      // 截取新增的替换内容
      String regexMatchedSubstitution = sb_content_Replaced.substring(beforeLength, afterLength);
      arr_regexMatchedSubstitution.add(regexMatchedSubstitution);
    }
    matcher.appendTail(sb_content_Replaced);

    System.out.println(sb_content_Replaced); // Sample enstence: naske, nasil, nosw, pisder
    System.out.println(arr_regexMatchedWord); // [sen, sna, sna, sno, spi]
    System.out.println(arr_regexMatchedSubstitution); // [ens, nas, nas, nos, pis]
  }
}

方法2:手动解析替换模板(需处理转义)

将替换模板中的$n替换为对应的matcher.group(n),注意处理转义字符(比如\$表示字面量$):

private static String getReplacementResult(Matcher matcher, String replacement) {
    StringBuilder result = new StringBuilder();
    int i = 0;
    int len = replacement.length();
    while (i < len) {
        char c = replacement.charAt(i);
        if (c == '\\') {
            // 处理转义字符,直接追加下一个字符
            if (i + 1 < len) {
                result.append(replacement.charAt(i + 1));
                i += 2;
            } else {
                // 末尾的转义符,直接追加
                result.append(c);
                i++;
            }
        } else if (c == '$') {
            // 处理分组引用
            if (i + 1 < len && Character.isDigit(replacement.charAt(i + 1))) {
                int groupNum = Character.getNumericValue(replacement.charAt(i + 1));
                result.append(matcher.group(groupNum));
                i += 2;
            } else {
                // 字面量$,直接追加
                result.append(c);
                i++;
            }
        } else {
            result.append(c);
            i++;
        }
    }
    return result.toString();
}

调用时直接在find()后使用:

String regexMatchedSubstitution = getReplacementResult(matcher, regexStrSubstitution);
arr_regexMatchedSubstitution.add(regexMatchedSubstitution);

方法3:反射(不推荐,依赖内部实现)

通过反射调用Matcher的私有方法appendExpandedReplacement来生成替换结果,但这种方法依赖JDK内部实现,版本更新可能导致失效:

import java.lang.reflect.Method;

private static String getReplacementViaReflection(Matcher matcher, String replacement) throws Exception {
    StringBuilder result = new StringBuilder();
    Method method = Matcher.class.getDeclaredMethod("appendExpandedReplacement", String.class, StringBuilder.class);
    method.setAccessible(true);
    method.invoke(matcher, replacement, result);
    return result.toString();
}

其他语言实现

JavaScript

JavaScript的replace方法支持传入函数作为替换器,函数的返回值就是本次替换结果,可以直接捕获:

const content = "Sample sentence: snake, snail, snow, spider";
const regex = /(s)(.)(.)/g;

const matchedWords = [];
const replacementResults = [];

const replacedContent = content.replace(regex, (match, p1, p2, p3) => {
    matchedWords.push(match);
    // 生成替换结果
    const replacement = p2 + p3 + p1;
    replacementResults.push(replacement);
    return replacement;
});

console.log(replacedContent); // Sample enstence: naske, nasil, nosw, pisder
console.log(matchedWords); // ["sen", "sna", "sna", "sno", "spi"]
console.log(replacementResults); // ["ens", "nas", "nas", "nos", "pis"]

Python

Python的re.sub方法支持回调函数,函数接收匹配对象,返回替换内容,同时可以记录替换结果:

import re

content = "Sample sentence: snake, snail, snow, spider"
pattern = r"(s)(.)(.)"

matched_words = []
replacement_results = []

def replace_callback(match):
    matched_words.append(match.group())
    # 生成替换结果
    replacement = match.group(2) + match.group(3) + match.group(1)
    replacement_results.append(replacement)
    return replacement

replaced_content = re.sub(pattern, replace_callback, content)

print(replaced_content) # Sample enstence: naske, nasil, nosw, pisder
print(matched_words) # ['sen', 'sna', 'sna', 'sno', 'spi']
print(replacement_results) # ['ens', 'nas', 'nas', 'nos', 'pis']

内容的提问来源于stack exchange,提问作者Nor.Z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:30:46