String.split() 是 Java 中最常用的字符串分割方法,它可以根据一个正则表达式将字符串拆分成一个字符串数组 (String[])。

基本语法
split 方法有两个重载版本:
// 版本1: 根据给定的正则表达式分割字符串 public String[] split(String regex) // 版本2: 根据给定的正则表达式分割字符串,并限制分割的次数 public String[] split(String regex, int limit)
regex: 分隔符的正则表达式。limit: 分割的次数限制。limit > 0:则分割最多limit - 1次, resulting array 的长度不会超过limit。limit < 0:则分割次数没有限制,这是最常见的用法。limit == 0:则分割次数没有限制,并且结尾的空字符串会被丢弃。
简单示例
示例 1:使用逗号分割
这是最经典的用法,但需要注意正则表达式的特殊性。
String str = "apple,banana,orange,grape";
String[] fruits = str.split(",");
// 遍历输出结果
for (String fruit : fruits) {
System.out.println(fruit);
}
输出:
apple
banana
orange
grape
示例 2:使用多个空格分割
String str = "Hello Java World";
// 使用 "\\s+" 来匹配一个或多个空白字符(空格、制表符等)
String[] words = str.split("\\s+");
for (String word : words) {
System.out.println(word);
}
输出:

Hello
Java
World
limit 参数详解
limit 参数非常有用,可以控制分割的行为。
示例 3:limit > 0
String str = "a,b,c,d,e";
// 限制最多分割 2 次,结果数组最多有 3 个元素
String[] parts = str.split(",", 3);
for (String part : parts) {
System.out.println(part);
}
输出:
a
b
c,d,e
可以看到,字符串只在第一个和第二个逗号处被分割,剩下的部分 c,d,e 作为一个整体被保留。
示例 4:limit == 0
limit == 0 和 limit < 0 在大多数情况下行为相同,但有一个关键区别:它会丢弃结果末尾的空字符串。

String str1 = "a,,b,,"; // 末尾有连续的逗号,会产生空字符串
String[] parts1 = str1.split(","); // 相当于 split(",", -1)
System.out.println("split(\",\") 的结果长度: " + parts1.length); // 输出 5
String[] parts2 = str1.split(",", 0);
System.out.println("split(\",\", 0) 的结果长度: " + parts2.length); // 输出 2
分析:
split(",")(或split(",", -1)) 会分割所有逗号,包括末尾的,得到["a", "", "b", "", ""],长度为 5。split(",", 0)也会分割所有逗号,但会丢弃结果末尾的空字符串,得到["a", "", "b"],长度为 2。
重要注意事项:regex 是正则表达式!
这是 split 方法最容易出错的地方,你传入的 regex 参数是一个正则表达式,而不是一个普通的字符串,这意味着一些在正则表达式中有特殊含义的字符,如果直接用作分隔符,需要转义。
常见需要转义的特殊字符:
| 字符 | 正则表达式中的含义 | 如何转义 |
|---|---|---|
| 任意单个字符 | \\. |
|
| "或" (选择) | \\| |
|
| 前一个字符 0 次或多次 | \\* |
|
| 前一个字符 1 次或多次 | \\+ |
|
| 前一个字符 0 次或 1 次 | \\? |
|
| 分组的开始 | \\( |
|
| 分组的结束 | \\) |
|
[ |
字符类的开始 | \\[ |
] |
字符类的结束 | \\] |
| 量词的开始 | \\{ |
|
| 量词的结束 | \\} |
|
^ |
字符串的开始或在字符类中表示“非” | \\^ |
| 字符串的结束 | \\$ |
|
\ |
转义字符本身 | \\\\ |
错误示例与修正
错误:
// 想用点 "." 分割 IP 地址 "192.168.1.1"
String ip = "192.168.1.1";
String[] ips = ip.split("."); // 错误!
// 输出结果: ["192", "168", "1", "1"] ??? 看起来好像对了?
// "." 在正则中匹配任意字符,它会匹配 "192.168.1.1" 中的每一个字符,
// 所以会分割成 ["", "", "", "", ...] 一堆空字符串。
// 在某些情况下,由于字符串长度或 JVM 优化,可能会出现看似正确的结果,但这绝对是错误的用法。
正确:
必须对点进行转义,使用两个反斜杠 \\。
String ip = "192.168.1.1";
String[] ips = ip.split("\\."); // 正确!
for (String s : ips) {
System.out.println(s);
}
输出:
192
168
1
1
另一个例子:分割文件路径
String path = "C:\\Users\\John\\Documents";
// 想用反斜杠 "\\" 分割,但反斜杠在字符串中也需要转义
// 所以一个反斜杠在字符串中要写成 "\\"
// 而在正则表达式中,反斜杠也需要转义,所以是 "\\\\"
String[] parts = path.split("\\\\"); // 正确!
for (String part : parts) {
System.out.println(part);
}
输出:
C:
Users
John
Documents
高级用法:使用正则表达式
split 的强大之处在于它支持复杂的正则表达式作为分隔符。
示例 5:使用多种分隔符
假设我们想用逗号、分号或竖线来分割字符串。
String str = "apple,banana;orange|grape";
// 使用正则表达式 "[,;|]" 表示匹配 "逗号"、"分号" 或 "竖线" 中的任意一个
String[] fruits = str.split("[,;|]");
for (String fruit : fruits) {
System.out.println(fruit);
}
输出:
apple
banana
orange
grape
替代方案:StringTokenizer
在非常古老的 Java 版本中,还有一个 StringTokenizer 类可以用来分割字符串,它不支持正则表达式,而是将每个字符作为分隔符。
StringTokenizer st = new StringTokenizer("apple, banana; orange", ",; ");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
输出:
apple
banana
orange
StringTokenizer vs String.split()
| 特性 | String.split() | StringTokenizer |
| :--- | :--- | :--- |
| 分隔符 | 支持正则表达式 | 只能是单个字符 |
| 返回类型 | String[] 数组 | Enumeration 对象,需遍历 |
| 处理空字符串 | 能保留结果中的空字符串 | 默认会跳过分隔符之间的空字符串 |
| 现代性 | 现代,推荐使用 | 遗留类,不推荐在新代码中使用 |
除非有特殊需求(比如性能要求极高且分隔符非常简单),否则总是优先使用 String.split()。
最佳实践总结
- 永远记住
regex是正则表达式:如果分隔符是 , , , , , , , ,[, ,\等特殊字符,必须使用\\进行转义。 - 处理空白字符:分割空格、制表符等时,使用
\\s+来匹配一个或多个连续的空白字符,避免产生空字符串。 - 了解
limit参数:当你只需要分割字符串的前几部分时,使用limit > 0可以提高效率并简化逻辑。 - 警惕末尾的空字符串:如果字符串末尾有分隔符,
split会产生空字符串,如果不需要这些空字符串,可以使用split(regex, 0)。 - 优先使用
split():在现代 Java 开发中,String.split()是功能最强大、最灵活的字符串分割工具。
