ZetCode

Java Matcher.replaceAll 方法

上次修改时间:2025 年 4 月 20 日

Matcher.replaceAll 方法是 Java 正则表达式包中的一个强大工具。 它将输入序列中与给定模式匹配的每个子序列替换为给定的替换字符串。此方法是 java.util.regex.Matcher 类的一部分。

replaceAll 扫描整个输入字符串,并替换所有与模式匹配的内容。 替换字符串可以包含对来自模式的捕获组的引用。这使得它对复杂的文本转换很有用。

基本定义

一个 Matcher 是从一个 Pattern 对象创建的,并将正则表达式模式应用于输入文本。replaceAll 方法执行全局查找和替换操作。 它返回一个新字符串,其中所有匹配项都已被替换。

替换字符串可以包括特殊序列,例如 $n 以引用捕获的组。 替换字符串中的反斜杠和美元符号可能需要转义。该方法会自动处理所有这些。

简单的文本替换

此示例演示了 replaceAll 的最基本用法。 我们将替换字符串中所有出现的单词。该模式匹配 “apple”,并将其替换为 “orange”。

SimpleReplace.java
package com.zetcode;

import java.util.regex.*;

public class SimpleReplace {
    public static void main(String[] args) {
        String input = "I have an apple, you have an apple, we all have apples.";
        Pattern pattern = Pattern.compile("apple");
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll("orange");
        System.out.println("Original: " + input);
        System.out.println("Modified: " + result);
    }
}

代码为单词 “apple” 创建一个 Pattern,并为输入字符串创建一个 Matcher。 replaceAll 扫描整个字符串并替换所有出现的匹配项。 请注意,它将 “apples” 替换为 “oranges”,因为该模式匹配了该单词的一部分。

不区分大小写的替换

此示例展示了如何执行不区分大小写的替换。 我们将使用 CASE_INSENSITIVE 标志来匹配任何大小写的 “hello”,并将其替换为 “Hi”。

CaseInsensitiveReplace.java
package com.zetcode;

import java.util.regex.*;

public class CaseInsensitiveReplace {
    public static void main(String[] args) {
        String input = "Hello world, hElLo Java, hello everyone!";
        Pattern pattern = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll("Hi");
        System.out.println("Original: " + input);
        System.out.println("Modified: " + result);
    }
}

CASE_INSENSITIVE 标志使模式匹配无论大小写如何。 所有 “hello” 的变体都将替换为 “Hi”。 替换字符串将完全按照指定的方式应用,无需大小写修改。

在替换中使用组引用

此示例演示了在替换字符串中使用捕获组。 我们将通过引用捕获组将日期从 “MM/DD/YYYY” 重新格式化为 “YYYY-MM-DD”。

GroupReferenceReplace.java
package com.zetcode;

import java.util.regex.*;

public class GroupReferenceReplace {
    public static void main(String[] args) {
        String input = "Today is 04/20/2023, tomorrow is 04/21/2023.";
        Pattern pattern = Pattern.compile("(\\d{2})/(\\d{2})/(\\d{4})");
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll("$3-$1-$2");
        System.out.println("Original: " + input);
        System.out.println("Modified: " + result);
    }
}

该模式将月、日和年捕获到组 1、2 和 3 中。 替换字符串 "$3-$1-$2" 重新排列这些组。 每个匹配项都将首先替换为年,然后是月,然后是日,用连字符分隔。

删除所有数字

此示例展示了如何通过将所有数字替换为空字符串来从字符串中删除它们。 我们将使用 \d 字符类,它匹配任何数字。

RemoveDigits.java
package com.zetcode;

import java.util.regex.*;

public class RemoveDigits {
    public static void main(String[] args) {
        String input = "Order 12345 has 3 items costing $456.78 total.";
        Pattern pattern = Pattern.compile("\\d");
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll("");
        System.out.println("Original: " + input);
        System.out.println("Modified: " + result);
    }
}

模式 \d 匹配每个单独的数字。 使用空字符串的 replaceAll 将删除所有匹配项。 请注意,这会分别删除每个数字,而不是作为整体单元的整个数字。

转义替换中的特殊字符

此示例演示了如何处理替换字符串中的特殊字符。 我们将用包含美元符号的字符串替换单词,这些美元符号在替换中是特殊的。

EscapeReplace.java
package com.zetcode;

import java.util.regex.*;

public class EscapeReplace {
    public static void main(String[] args) {
        String input = "Price: 100, Cost: 75, Profit: 25";
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll("\\$$0");
        System.out.println("Original: " + input);
        System.out.println("Modified: " + result);
    }
}

要在替换中包含字面美元符号,我们使用反斜杠对其进行转义。 $0 引用整个匹配项。 结果是在每个数字前加上美元符号。 注意 Java 字符串中的双反斜杠。

多行替换

此示例显示了如何在多行中执行替换。 我们将使用 MULTILINE 标志来匹配每行开头的模式。

MultilineReplace.java
package com.zetcode;

import java.util.regex.*;

public class MultilineReplace {
    public static void main(String[] args) {
        String input = "First line\nSecond line\nThird line";
        Pattern pattern = Pattern.compile("^", Pattern.MULTILINE);
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll("• ");
        System.out.println("Original:\n" + input);
        System.out.println("Modified:\n" + result);
    }
}

模式 ^ 通常只匹配整个字符串的开头。 使用 MULTILINE 标志,它匹配每行的开头。 我们将这些位置替换为项目符号字符,有效地为每一行添加项目符号。

使用 Lambda 的复杂替换

Java 9 引入了使用函数进行替换。 此示例显示了如何使用 lambda 来执行基于匹配内容动态替换。

LambdaReplace.java
package com.zetcode;

import java.util.regex.*;

public class LambdaReplace {
    public static void main(String[] args) {
        String input = "3 apples, 12 oranges, 1 banana";
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(input);
        
        String result = matcher.replaceAll(match -> {
            int num = Integer.parseInt(match.group());
            return String.valueOf(num * 2);
        });
        System.out.println("Original: " + input);
        System.out.println("Modified: " + result);
    }
}

对于每个匹配项,lambda 将匹配的文本转换为整数,将其加倍,然后转换回字符串。 这演示了仅使用静态替换字符串无法实现的复杂、动态替换。

来源

Java Matcher.replaceAll 文档

Matcher.replaceAll 方法对于 Java 中的文本处理至关重要。 这些示例演示了它在处理从简单到复杂的各种替换方案中的灵活性。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员,在这一领域拥有多年的经验。 我从 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和 8 本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程