split() 使用的是正则表达式
String.split(String regex) 方法的参数是一个正则表达式,而不是一个普通的字符串,这意味着,如果你想在分割时使用像 、、、、、、、[、]、、、\、^、 等字符,你必须对它们进行转义,否则它们会被当作正则表达式的元字符来处理,导致不符合预期的结果。

需要转义的特殊字符列表
以下字符在正则表达式中有特殊含义,在 split() 中用作分割符时必须用反斜杠 \ 进行转义:
| 字符 | 正则表达式中的含义 | 转义后的写法 | 示例分割字符串 | 预期分割结果 |
|---|---|---|---|---|
| 任意单个字符 | \\. |
"1.2.3.4" |
["1", "2", "3", "4"] |
|
| "或" 逻辑 | \\| |
"a|b|c" |
["a", "b", "c"] |
|
| 0次或多次重复 | \\* |
"a*b*c" |
["a", "b", "c"] |
|
| 1次或多次重复 | \\+ |
"a+b+c" |
["a", "b", "c"] |
|
| 0次或1次重复 | \\? |
"a?b?c" |
["a", "b", "c"] |
|
| 分组开始 | \\( |
"a(b)c" |
["a", "b", "c"] |
|
| 分组结束 | \\) |
"a)b)c" |
["a", "b", "c"] |
|
[ |
字符类开始 | \\[ |
"a[b]c" |
["a", "b", "c"] |
] |
字符类结束 | \\] |
"a]b]c" |
["a", "b", "c"] |
| 量词开始 | \\{ |
"a{b}c" |
["a", "b", "c"] |
|
| 量词结束 | \\} |
"a}b}c" |
["a", "b", "c"] |
|
\ |
转义字符本身 | \\\\ |
"a\\b\\c" |
["a", "b", "c"] |
^ |
字符串开始或"非" | \\^ |
"a^b^c" |
["a", "b", "c"] |
| 字符串结束 | \\$ |
"a$b$c" |
["a", "b", "c"] |
转义的正确方法:双反斜杠 \\
在 Java 字符串中,一个反斜杠 \ 本身就是一个转义字符。\n 代表换行,\t 代表制表符。
如果你想在字符串中表示一个字面上的反斜杠 \,你需要写成 \\。
当 split() 方法接收到一个字符串参数时,它会先将字符串中的转义序列解释掉,然后将结果作为正则表达式进行编译。

为了在正则表达式中得到一个 \,你需要在 Java 字符串中写成 \\。
举个例子:
- 你想用 作为分隔符。
- 在正则表达式中,你需要
\\.。 - 在 Java 字符串中,你需要写成
"\\."。
代码示例:
public class SpecialCharSplit {
public static void main(String[] args) {
String text = "apple.banana.orange";
// 错误示范:. 在正则中是"任意字符",会分割所有字符
// 结果: ["a", "p", "p", "l", "e", "b", "a", "n", "a", "n", "a", "o", "r", "a", "n", "g", "e"]
String[] wrongSplit = text.split(".");
System.out.println("错误示范 (split('.')):");
for (String s : wrongSplit) {
System.out.print(s + " ");
}
System.out.println("\n------------------------");
// 正确示范:使用 \\.
String[] correctSplit = text.split("\\.");
System.out.println("正确示范 (split(\"\\\\.\")):");
for (String s : correctSplit) {
System.out.print(s + " ");
}
System.out.println("\n------------------------");
// 另一个例子:用 | 分割
String text2 = "red|green|blue";
// 正确示范:使用 \\|
String[] pipeSplit = text2.split("\\|");
System.out.println("用 | 分割 (split(\"\\\\|\")):");
for (String s : pipeSplit) {
System.out.print(s + " ");
}
System.out.println("\n------------------------");
// 最复杂的例子:用 \ 分割
String text3 = "C:\\Program Files\\Java\\jdk";
// 正确示范:需要四个反斜杠 \\\\ 来表示一个字面上的 \
// 1. Java字符串解释 \\ -> \
// 2. 正则表达式解释 \\ -> \
String[] backslashSplit = text3.split("\\\\");
System.out.println("用 \\ 分割 (split(\"\\\\\\\\\")):");
for (String s : backslashSplit) {
System.out.print(s + " ");
}
}
}
输出结果:

错误示范 (split('.')):
a p p l e b a n a n a o r a n g e
------------------------
正确示范 (split("\.\")):
apple banana orange
------------------------
用 | 分割 (split("\\|")):
red green blue
------------------------
用 \ 分割 (split("\\\\\\")):
C: Program Files Java jdk
Pattern.quote() - 最佳实践
当你想将一个固定的字符串(而不是一个正则表达式)用作分割符时,手动转义所有特殊字符是一件繁琐且容易出错的事情,Java 提供了一个更好的方法:java.util.regex.Pattern.quote()。
这个方法会接受一个字符串,并返回一个字面量字符串的正则表达式模式,它会自动为你处理所有需要转义的字符。
语法:
String[] parts = input.split(Pattern.quote(your_delimiter));
代码示例:
import java.util.regex.Pattern;
public class PatternQuoteExample {
public static void main(String[] args) {
String text = "a.b*c+d?e(f)g[h]i{j}k\\l^m$n";
String delimiter = ".+?()[]{}\\^$"; // 包含所有特殊字符的分割符
// 使用 Pattern.quote(),无需手动转义
String[] parts = text.split(Pattern.quote(delimiter));
System.out.println("原始字符串: " + text);
System.out.println("分割符: " + delimiter);
System.out.println("分割结果:");
for (String part : parts) {
System.out.print(part + " "); // 输出: a b c d e f g h i j k l m n
}
}
}
为什么 Pattern.quote() 更好?
- 安全:你不需要记住所有特殊字符并手动转义,避免了因遗漏而出错。
- 清晰:代码意图更清晰。
Pattern.quote(delimiter)明确表示“将delimiter视为普通字符串来分割”,而不是“将delimiter视为正则表达式”。 - 可维护性:如果未来 Java 的正则表达式规范增加了新的元字符,使用
Pattern.quote()的代码仍然可以正常工作,而手动转义的代码可能需要更新。
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
手动转义 (\\.) |
分割符是单个、已知的特殊字符 | 简单直接 | 容易出错,代码可读性差,需要记住所有元字符 |
Pattern.quote() |
推荐,分割符是任意字符串,特别是包含特殊字符时 | 安全、清晰、可维护性好 | 需要导入 java.util.regex.Pattern |
最佳实践建议:
只要你的分割符可能包含任何特殊字符,或者你不确定它是否包含特殊字符,就应该优先使用 Pattern.quote(),只有在性能要求极高且分割符是确定不变的简单字符时,才考虑手动转义,在绝大多数业务场景下,Pattern.quote() 是更优、更安全的选择。
