| 維度 | replace() | replaceAll() |
|---|---|---|
| 參數類型 | CharSequence / char | String regex (正則表達式) |
| 匹配語義 | 字面量精確匹配 | 正則模式匹配 |
| 替換範圍 | 全局替換 | 全局替換 |
| 性能 | 極快 (無正則解析) | 較慢 (需編譯正則) |
| 特殊字符處理 | 無需轉義 | 需雙重轉義 |
// 字符替換
"hello".replace('l', 'x') // "hexxo"
// 字符串替換 (CharSequence)
"hello world".replace("l", "x") // "hexxo worxd"
"hello".replace("ll", "xx") // "hexxo"
// 不支持正則
"a1b2c3".replace("\\d", "#") // "a1b2c3" (字面量匹配 "\\d")
// 正則替換所有數字
"a1b2c3".replaceAll("\\d", "#") // "a#b#c#"
// 正則替換連續數字
"abc123def456".replaceAll("\\d+", "X") // "abcXdefX"
// 分組引用替換
"2024-01-15".replaceAll("(\\d{4})-(\\d{2})-(\\d{2})", "$3/$2/$1") // "15/01/2024"
// 僅替換首次匹配
"a1b2c3".replaceFirst("\\d", "#") // "a#b2c3"
| 操作 | 吞吐量 | 備註 |
|---|---|---|
| replace("a", "b") | ~25,000 ops/ms | 字面量極快 |
| replaceAll("a", "b") | ~8,000 ops/ms | 簡單正則 |
| replaceAll("\\d", "#") | ~5,000 ops/ms | 字符類正則 |
| 預編譯 Pattern | ~12,000 ops/ms | 高頻場景優化 |
// 目標:將 "\" 替換為 "\\"
// Java 字符串轉義:\\ 代表 \
// 正則轉義:\\ 代表 \
// 結合:需要 4 個反斜槓
String path = "C:\\Users\\Admin";
path.replaceAll("\\\\", "/"); // "C:/Users/Admin"
// 更複雜:將 "\\" 替換為 "\\\\"
msgOut = msgIn.replaceAll("\\\\\\\\", "\\\\\\\\\\\\\\\\");
// 層層解碼:Java字符串 -> 正則引擎 -> 實際匹配
口訣:Java 層轉義一次,正則層轉義一次,共兩次。
// 目標替換 "."
"1.2.3".replaceAll(".", "#") // "###" 錯誤!. 匹配任意字符
"1.2.3".replaceAll("\\.", "#") // "1#2#3" 正確
"1.2.3".replace(".", "#") // "1#2#3" replace() 無此問題
正則元字符:. * + ? ^ $ { } [ ] | ( ) \ 使用 replaceAll 時必須轉義。
"abc".replaceAll("", "-") // "-a-b-c-" (每個字符間+首尾插入)
"abc".replace("", "-") // "-a-b-c-" 同理
str.replace("a", null) // NPE
str.replaceAll("a", null) // NPE
str.replace(null, "b") // NPE
private static final Pattern DIGITS = Pattern.compile("\\d+");
public static String maskDigits(String input) {
return DIGITS.matcher(input).replaceAll("*"); // 復用 Pattern
}
// String.replace(CharSequence target, CharSequence replacement)
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL)
.matcher(this)
.replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
// 內部實際調用了 Pattern + Matcher,但 Pattern.LITERAL 模式禁用正則語義
// 所以 replace() 本質是「字面量模式的 replaceAll」
理解兩者本質區別:replace = 字面量全局替換,replaceAll = 正則全局替換。選對工具,代碼更簡潔、性能更高、Bug 更少。