String.split(String regex) 參數是正則表達式而非純字串,這是無數開發者踩坑的根源。本文系統整理特殊字元轉義、多重分隔符、限制長度、效能陷阱四大核心場景,提供可直接複製的最佳實踐。
split("|") 為何產生空字串?"2|33|4".split("|")
// 結果:["", "2", "", "", "3", "3", "", "", "4"]
原因:| 在正則中是「或」運算符,"" (空字串) 匹配任意位置 → 每個字元間都被切割。
| 字元 | 正則含義 | 正確寫法 | Java 字串寫法 |
|---|---|---|---|
. | 任意單一字元 | \. | "\\." |
| | 或運算 | \| | "\\|" |
* | 零或多次 | \* | "\\*" |
+ | 一次或多次 | \+ | "\\+" |
? | 零或一次 | \? | "\\?" |
[ ] | 字元類別 | \[ \] | "\\[", "\\]" |
( ) | 分組捕獲 | \( \) | "\\(", "\\)" |
{ } | 量詞範圍 | \{ \} | "\\{", "\\}" |
^ $ | 行首/行尾 | \^ \$ | "\\^", "\\$" |
\ | 轉義字元 | \\ | "\\\\" |
"192.168.1.1".split("\\.") // IP 切割
"a|b|c".split("\\|") // 管道符切割
"C:\\Windows\\System32".split("\\\\") // 路徑切割(雙重轉義)
"a=1 and b=2 or c=3".split("and|or")
// 結果:["a=1 ", " b=2 ", " c=3"]
技巧:直接在正則中用 | 連接多個分隔符,無需循環多次 split。
limit 參數)"a,b,c,d".split(",", 2) // ["a", "b,c,d"] 最多 2 個元素
"a,b,c,d".split(",", 0) // ["a", "b", "c", "d"] 預設行為,移除尾部空字串
"a,b,c,d".split(",", -1) // ["a", "b", "c", "d", ""] 保留尾部空字串
高頻呼叫時,避免重複編譯正則:
// ❌ 每次呼叫都編譯正則
String[] parts = input.split("\\|");
// ✅ 預編譯 Pattern 重複使用
private static final Pattern PIPE_PATTERN = Pattern.compile("\\|");
public String[] splitFast(String input) {
return PIPE_PATTERN.split(input);
}
基準測試:100 萬次分割,Pattern.split 比 String.split 快 3~5 倍。
| 錯誤寫法 | 現象 | 修正寫法 |
|---|---|---|
str.split(".") | 切成單一字元陣列 | str.split("\\.") |
str.split("|") | 產生大量空字串 | str.split("\\|") |
str.split("*") | PatternSyntaxException | str.split("\\*") |
str.split("\\") | PatternSyntaxException | str.split("\\\\") |
| 連接split(regex, -1)PatternStringTokenizer 或 indexOf 手寫更快