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" |
关键区别:
replaceAll和replaceFirst使用正则表达式。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."
replaceAll是强大的字符串替换工具,基于正则表达式。- 第一个参数是正则表达式,不是普通字符串,要小心 、、 等元字符的特殊含义,如果需要匹配这些字符本身,请使用
\\进行转义。 - 第二个参数是替换字符串,可以使用
$&、$、$'、$n等特殊序列。 - 它不修改原字符串,而是返回一个新的字符串。
- 区分
replaceAll、replaceFirst和replace:- 需要正则且全部替换 ->
replaceAll - 需要正则且只替换第一个 ->
replaceFirst - 需要普通字符串匹配 ->
replace(通常更安全、更高效)
- 需要正则且全部替换 ->
