1. 概述

在本教程中,我们将探讨在 Java 中删除或替换字符串(String)部分内容的各种方法。

我们会先通过 String 类自带的 API 实现替换与删除操作,接着使用 StringBuilder 的 API 来处理,最后介绍 Apache Commons 库中的 StringUtils 工具类。
作为扩展,我们还会讨论一些常见的字符串替换问题,比如替换精确单词、删除字符直到某个特定字符等。

2. 使用 String API

最简单直接的方式是使用 String 类提供的 replace()replaceAll()replaceFirst() 方法来替换子串。

其中 replace() 方法接受两个参数:目标字符串和替换字符串:

String master = "Hello World Baeldung!";
String target = "Baeldung";
String replacement = "Java";
String processed = master.replace(target, replacement);
assertTrue(processed.contains(replacement));
assertFalse(processed.contains(target));

上述代码的输出结果为:

Hello World Java!

如果需要使用正则表达式匹配目标内容,则应选择 replaceAll()replaceFirst()。顾名思义,replaceAll() 会替换所有匹配项,而 replaceFirst() 只替换第一个匹配项:

String master2 = "Welcome to Baeldung, Hello World Baeldung";
String regexTarget = "(Baeldung)$";
String processed2 = master2.replaceAll(regexTarget, replacement);
assertTrue(processed2.endsWith("Java"));

此时 processed2 的值为:

Welcome to Baeldung, Hello World Java

因为提供的正则表达式 (Baeldung)$ 只匹配最后一个 “Baeldung”。
提示:以上所有示例中,我们都可以传入空字符串作为 replacement,从而实现“移除”目标字符串的效果。

3. 使用 StringBuilder API

除了 String 类外,我们还可以使用 StringBuilder 类来进行更灵活的字符串修改操作。它提供了 delete()replace() 方法。

我们可以从已有字符串构造一个 StringBuilder 实例,然后进行操作:

String master = "Hello World Baeldung!";
String target = "Baeldung";
String replacement = "Java";

int startIndex = master.indexOf(target);
int stopIndex = startIndex + target.length();

StringBuilder builder = new StringBuilder(master);

接下来,使用 delete() 移除目标字符串:

builder.delete(startIndex, stopIndex);
assertFalse(builder.toString().contains(target));

也可以使用 replace() 替换目标字符串:

builder.replace(startIndex, stopIndex, replacement);
assertTrue(builder.toString().contains(replacement));

⚠️ 注意:与 String API 不同的是,使用 StringBuilder 需要手动计算目标子串的起始和结束索引。

4. 使用 StringUtils 工具类

Apache Commons Lang 库中的 StringUtils 提供了更多实用的字符串操作方法。

首先添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.14.0</version>
</dependency>

最新版本可以在 Maven Repository 找到。

使用 StringUtils.replace() 替换字符串:

String master = "Hello World Baeldung!";
String target = "Baeldung";
String replacement = "Java";

String processed = StringUtils.replace(master, target, replacement);
assertTrue(processed.contains(replacement));

该方法还有一个重载版本,支持传入一个 max 参数,用于限制替换次数。
如果忽略大小写,可以使用 replaceIgnoreCase() 方法:

String master2 = "Hello World Baeldung!";
String target2 = "baeldung";
String processed2 = StringUtils.replaceIgnoreCase(master2, target2, replacement);
assertFalse(processed2.contains(target));

5. 替换精确单词

在实际开发中,我们可能只想替换字符串中的完整单词,而不是部分匹配的内容。

为此,可以使用正则表达式配合单词边界 \b

String sentence = "A car is not the same as a carriage, and some planes can carry cars inside them!";
String regexTarget = "\\bcar\\b";
String exactWordReplaced = sentence.replaceAll(regexTarget, "truck");

结果为:

"A truck is not the same as a carriage, and some planes can carry cars inside them!"

注意:Java 中的反斜杠必须转义,因此正则表达式中的 \b 写成 \\b

你也可以使用 Apache Commons 的 RegExUtils 类实现相同功能:

String regexTarget = "\\bcar\\b";
String exactWordReplaced = RegExUtils.replaceAll(sentence, regexTarget, "truck");

两种方式效果一致,选择哪个取决于你的项目依赖和使用习惯。

6. 删除字符直到指定字符

在真实项目中,我们有时需要从字符串中删除直到某个字符的内容。下面举两个例子说明“包含”与“不包含”目标字符的场景。

示例 1(包含目标字符):

static final String INPUT1 = "some prefix=Important Info: a=b";

我们的目标是删除从开头到第一个 = 的内容(包括 =),得到:

Important Info: a=b

示例 2(不包含目标字符):

static final String INPUT2 = "some prefix<a, <b, c>>"

目标是删除到第一个 < 为止(不包括 <),得到:

<a, <b, c>>

6.1. 使用 indexOf()substring()

这是最直观的方法:

String result1 = INPUT1.substring(INPUT1.indexOf("=") + 1);
assertEquals("Important Info: a=b", result1);

说明:+1 是为了跳过 = 字符。

对于“不包含”的情况,去掉 +1 即可:

String result2 = INPUT2.substring(INPUT2.indexOf("<"));
assertEquals("<a, <b, c>>", result2);

6.2. 使用 split()

将字符串按分隔符切分为数组,取后半部分:

String result1 = INPUT1.split("=", 2)[1];
assertEquals("Important Info: a=b", result1);

对于“不包含”的情况,可以使用正向预查(lookahead):

String result2 = INPUT2.split("(?=<)", 2)[1];
assertEquals("<a, <b, c>>", result2);

6.3. 使用 replaceFirst()

通过正则表达式替换前缀部分:

String result1 = INPUT1.replaceFirst(".*?=", "");
assertEquals("Important Info: a=b", result1);

说明:.*?= 是非贪婪匹配,只匹配到第一个 =

或者使用字符类排除法:

result1 = INPUT1.replaceFirst("[^=]*=", "");
assertEquals("Important Info: a=b", result1);

对于“不包含”情况,只需去掉等号:

String result2 = INPUT2.replaceFirst("[^<]*", "");
assertEquals("<a, <b, c>>", result2);

7. 替换最后一次出现的文本

有时候我们需要替换字符串中最后一次出现的目标词,比如:

final static String INPUT3 = "The first word, the second word, the last word should be replaced.";

目标是将最后一个 “word” 替换为 “WORD”,得到:

final static String EXPECTED3 = "The first word, the second word, the last *WORD* should be replaced.";

7.1. 反转 + 替换 + 再反转

这个思路是:反转字符串,让最后一个变成第一个,然后使用 replaceFirst(),最后再反转回来。

String reverseString(String input) {
    return new StringBuilder(input).reverse().toString();
}

String theWord = "word";
String replacement = "*WORD*";

String reversedInput = reverseString(INPUT3);
String reversedTheWord = reverseString(theWord);
String reversedReplacement = reverseString(replacement);
String reversedResult = reversedInput.replaceFirst(reversedTheWord, reversedReplacement);

String result = reverseString(reversedResult);

assertEquals(EXPECTED3, result);

优点:思路清晰;缺点:多次反转,性能略差。

7.2. 使用 lastIndexOf() 方法

更直接的方式是使用 lastIndexOf() 定位最后一个出现位置,然后拼接前后部分:

String theWord = "word";
String replacement = "*WORD*";

int index = INPUT3.lastIndexOf(theWord);
String result = INPUT3.substring(0, index) + replacement + INPUT3.substring(index + theWord.length());

assertEquals(EXPECTED3, result);

推荐:这种方式更直观,性能更好。

8. 总结

在 Java 中删除或替换字符串部分内容有多种方式,各有优劣:

  • ✅ 简单替换用 String.replace() / replaceAll()
  • ⚠️ 需要索引控制时用 StringBuilder
  • ✅ 通用工具类推荐 StringUtils
  • ✅ 复杂匹配推荐正则表达式
  • ✅ 特定场景(如替换最后一个)推荐 lastIndexOf() + 拼接

完整代码示例可参考 GitHub 仓库:https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-string-algorithms-2


原始标题:Remove or Replace Part of a String in Java| Baeldung