杰瑞科技汇

Java中replaceAll如何正确使用?

replaceAll 是 Java String 类中的一个核心方法,用于替换字符串中所有匹配某个正则表达式的子串。


基本语法

replaceAll 方法的签名如下:

public String replaceAll(String regex, String replacement)

参数说明:

  • regex: 一个正则表达式(Regular Expression),用来定义要匹配的模式。
  • replacement: 一个字符串,用于替换所有匹配 regex 的子串。

返回值:

  • 返回一个新的字符串,其中所有匹配 regex 的子串都被 replacement 字符串替换。
  • 如果没有找到匹配项,则返回原始字符串的副本。
  • 注意String 对象是不可变的,replaceAll 不会修改原始字符串,而是返回一个新的字符串。

核心要点:regex 是正则表达式

这是理解 replaceAll 最重要的一点,它的第一个参数 regex 不是一个简单的字符串,而是一个正则表达式,这意味着它包含一些特殊的字符(元字符),具有特殊的含义。

常见的正则表达式元字符:

元字符 含义 示例 (replaceAll 使用)
匹配任意单个字符(除了换行符)。 "hello.world".replaceAll(".", "-") -> (匹配了每个字符)
匹配前面的子表达式零次或多次 "aaabbb".replaceAll("a*", "-") -> "-bbb-" (匹配了开头的 "aaa" 和中间的 "",即零个 'a')
匹配前面的子表达式一次或多次 "aaabbb".replaceAll("a+", "-") -> "-bbb" (匹配了开头的 "aaa",至少一次)
匹配前面的子表达式零次或一次 "color".replaceAll("colou?r", "-") -> (匹配 "color" 或 "colour")
^ 匹配输入字符串的开始位置 "hello world".replaceAll("^h", "H") -> "Hello world"
匹配输入字符串的结束位置 "hello world".replaceAll("d$", "D") -> "hello worlD"
\d 匹配一个数字 (等同于 [0-9])。 "abc123def".replaceAll("\\d", "x") -> "abcxxxdef"
\D 匹配一个非数字字符。 "abc123def".replaceAll("\\D", "x") -> "xxx123xxx"
\w 匹配单词字符 (字母, 数字, 下划线)。 "user_name_123".replaceAll("\\w", "-") -> "--------_---"
\W 匹配非单词字符 "user_name_123".replaceAll("\\W", "-") -> "user_name_123" (下划线是 \w)
[...] 匹配括号内的任意一个字符 "a1b2c3".replaceAll("[abc]", "x") -> "x1x2x3"
[^...] 匹配除了括号内字符之外的任意一个字符 "a1b2c3".replaceAll("[^abc]", "x") -> "axbxcx"
\s 匹配空白字符 (空格, 制表符 \t, 换行符 \n 等)。 "a b c".replaceAll("\\s", "-") -> "a-b-c"
\S 匹配非空白字符 "a b c".replaceAll("\\S", "-") ->

特别注意: 在 Java 字符串中,反斜杠 \ 是一个转义字符,所以如果你想表示正则表达式中的 \d,你需要在 Java 字符串中写成 "\\d",因为第一个 \ 用来转义第二个 \,这样才能得到一个真正的 \ 字符传递给正则表达式引擎。


replacement 参数的特殊含义

replacement 参数不仅可以是普通字符串,还可以包含一些特殊的序列,这些序列会与匹配到的内容进行替换。

特殊序列 含义
`$& 匹配整个正则表达式的子串。
`$' 匹配匹配子串之前的部分。
`$' 匹配匹配子串之后的部分。
`$n 匹配第 n 个捕获组 (capturing group),n 必须是 1 到 9。
$<name> | 匹配命名捕获组`。

replacement 示例:

String text = "one two three four";
// $& 表示匹配到的整个内容
String result1 = text.replaceAll("\\w+", "$&!");
// 结果: "one! two! three! four!"
// 解释:每个单词 (\w+) 被匹配到,然后用它自己加上 "!" 来替换。
// $` 表示匹配内容之前的字符串
String result2 = text.replaceAll("three", "$`");
// 结果: "one two one two four"
// 解释:当匹配到 "three" 时,它前面的内容是 "one two ",所以用 "one two " 替换 "three"。
// $' 表示匹配内容之后的字符串
String result3 = text.replaceAll("two", "$'");
// 结果: "one three four four"
// 解释:当匹配到 "two" 时,它后面的内容是 " three four",所以用 " three four" 替换 "two"。

replaceAll vs replace vs replaceFirst

这是一个非常常见的混淆点。

方法 描述 参数类型 示例
replaceAll 替换所有匹配正则表达式的子串。 regex (正则), replacement (字符串) "123".replaceAll("\\d", "x") -> "xxx"
replaceFirst 只替换第一个匹配正则表达式的子串。 regex (正则), replacement (字符串) "123".replaceFirst("\\d", "x") -> "x23"
replace 替换所有匹配普通字符串的子串。 target (普通字符串), replacement (字符串) "123".replace("1", "x") -> "x23"

关键区别:

  • replaceAllreplaceFirst 使用正则表达式
  • replace 使用普通字符串进行匹配,没有任何特殊含义。

陷阱示例: 假设你想把字符串中的所有点 替换成横线 。

String ip = "192.168.1.1";
// 错误用法!
// "." 在正则中匹配任意字符,所以会把 "192.168.1.1" 中的每个字符都替换掉。
String wrongResult = ip.replaceAll(".", "-"); 
// 结果: "--------" (8个横线)
// 正确用法:需要对正则中的特殊字符进行转义
String rightResult = ip.replaceAll("\\.", "-");
// 结果: "192-168-1-1"
// 或者更简单,使用 replace 方法
String simpleResult = ip.replace(".", "-");
// 结果: "192-168-1-1"

实用代码示例

示例 1:去除所有标点符号

String sentence = "Hello, World! This is a test.";
// [^a-zA-Z\\s] 匹配所有非字母和非空格的字符
String cleanSentence = sentence.replaceAll("[^a-zA-Z\\s]", "");
System.out.println(cleanSentence);
// 输出: "Hello World This is a test"

示例 2:格式化电话号码

String rawPhone = "1234567890";
// 使用捕获组 ( 和 ) 来提取部分号码
String formattedPhone = rawPhone.replaceAll("(\\d{3})(\\d{3})(\\d{4})", "($1) $2-$3");
System.out.println(formattedPhone);
// 输出: (123) 456-7890
  • \\d{3} 匹配3个数字。
  • (\\d{3}) 创建了一个捕获组,匹配到的内容可以用 $1 来引用。
  • $1 对应第一个捕获组 (\\d{3})
  • $2 对应第二个捕获组 (\\d{3})
  • $3 对应第三个捕获组 (\\d{4})

示例 3:规范化空白字符

将一个或多个连续的空白字符(空格、制表符、换行)替换成一个空格。

String messyText = "This  is a\t\nmessy  string.";
// \\s+ 匹配一个或多个连续的空白字符
String normalizedText = messyText.replaceAll("\\s+", " ");
System.out.println(normalizedText);
// 输出: "This is a messy string."

  1. replaceAll 是强大的字符串替换工具,基于正则表达式。
  2. 第一个参数是正则表达式,不是普通字符串,要小心 、、 等元字符的特殊含义,如果需要匹配这些字符本身,请使用 \\ 进行转义。
  3. 第二个参数是替换字符串,可以使用 $&、$、$'、$n 等特殊序列。
  4. 它不修改原字符串,而是返回一个新的字符串。
  5. 区分 replaceAllreplaceFirstreplace
    • 需要正则全部替换 -> replaceAll
    • 需要正则只替换第一个 -> replaceFirst
    • 需要普通字符串匹配 -> replace (通常更安全、更高效)
分享:
扫描分享到社交APP
上一篇
下一篇