String.split(String regex)
String 类中的 split() 方法可以根据给定的正则表达式来分割字符串,并返回一个字符串数组。

public String[] split(String regex)
关键点:这个方法的参数 regex 是一个正则表达式,而不仅仅是一个普通的字符串分隔符,这意味着你可以使用正则表达式的强大功能来进行复杂的分割。
基本用法:普通分隔符
对于最简单的场景,比如用逗号、空格等分割,split() 的使用非常直观。
示例 1:用逗号分割
String text = "apple,banana,orange";
String[] fruits = text.split(",");
// 输出结果
for (String fruit : fruits) {
System.out.println(fruit);
}
// 输出:
// apple
// banana
// orange
示例 2:用空格分割
String sentence = "Java is fun";
String[] words = sentence.split(" ");
// 输出结果
for (String word : words) {
System.out.println(word);
}
// 输出:
// Java
// is
// fun
正则表达式的威力
当分隔符变得复杂时,正则表达式就派上用场了。
示例 3:分割一个或多个空格
这是一个非常经典的例子,如果你直接用 split(" "),连续的空格会产生空字符串元素。

String textWithSpaces = "Java is fun";
// " " 只匹配单个空格
String[] words1 = textWithSpaces.split(" ");
// 输出: ["Java", "", "", "is", "", "", "", "fun"] -> 不理想
// 使用正则表达式 "\\s+" 来匹配一个或多个空白字符(空格、制表符等)
String[] words2 = textWithSpaces.split("\\s+");
// 输出: ["Java", "is", "fun"] -> 理想结果
注意:在 Java 字符串中,反斜杠 \ 是一个转义字符,所以要在字符串中表示一个正则表达式的 \s,你需要写成 \\s。
示例 4:分割多种分隔符
假设你想用逗号、分号或竖线来分割字符串。
String data = "apple,banana;orange|grape";
// 使用正则表达式 "[,;|]" 表示匹配 "、"、";" 或 "|" 中的任意一个
String[] items = data.split("[,;|]");
// 输出结果
for (String item : items) {
System.out.println(item);
}
// 输出:
// apple
// banana
// orange
// grape
示例 5:按分割后的长度分割
这是一个更高级的用法,假设你想用连续的数字作为分隔符。
String complexText = "abc123def456ghi";
// "\\d+" 匹配一个或多个数字
String[] parts = complexText.split("\\d+");
// 输出结果
for (String part : parts) {
System.out.println(part);
}
// 输出:
// abc
// def
// ghi
常见的“坑”与注意事项
坑 1:特殊字符需要转义
正则表达式中的特殊字符(, , , , ^, , , \, , , [, ], , )在作为普通分隔符时,必须用反斜杠 \ 进行转义。

| 分隔符 | 错误写法 | 正确写法 | 解释 |
|---|---|---|---|
| 点 | text.split(".") |
text.split("\\.") |
在正则中匹配任意字符,必须转义 |
| 竖线 | text.split("|") |
text.split("\\|") |
在正则中表示“或”,必须转义 |
| 星号 | text.split("*") |
text.split("\\*") |
在正则中表示“零次或多次”,必须转义 |
| 加号 | text.split("+") |
text.split("\\+") |
在正则中表示“一次或多次”,必须转义 |
| 问号 | text.split("?") |
text.split("\\?") |
在正则中表示“零次或一次”,必须转义 |
| 左括号 | text.split("(") |
text.split("\\(") |
在正则中表示分组,必须转义 |
示例:用点 分割
String path = "www.example.com";
// 错误! "." 会匹配任意字符,结果可能不是你想要的
// String[] parts1 = path.split(".");
// 正确!转义 "." 使其只匹配字面上的点 "."
String[] parts2 = path.split("\\.");
// 输出结果
for (String part : parts2) {
System.out.println(part);
}
// 输出:
// www
// example
// com
坑 2:尾部空字符串的处理
默认情况下,如果字符串的末尾有分隔符,split() 会保留一个空字符串在结果数组的末尾。
String text = "apple,orange,";
String[] fruits = text.split(",");
// 输出结果
for (String fruit : fruits) {
System.out.println("-> '" + fruit + "'");
}
// 输出:
// -> 'apple'
// -> 'orange'
// -> '' <-- 注意这里有一个空字符串
如果你不希望保留这个尾部的空字符串,可以使用 split() 的重载方法,并传入一个 limit 参数。
split(String regex, int limit) 参数详解
limit 参数控制分割的次数以及是否保留尾部的空字符串。
limit > 0: 最多分割limit - 1次,结果数组的长度最多为limit。limit < 0: 分割所有可能的位置,并保留所有尾部的空字符串。limit = 0: 分割所有可能的位置,并丢弃所有尾部的空字符串。(这是最常见的用法)
示例:使用 limit 参数
String text = "apple,orange,";
// limit = 0 (丢弃尾部空字符串)
String[] fruits1 = text.split(",", 0);
// 输出: ["apple", "orange"] <-- 尾部的空字符串被丢弃了
// limit = -1 (保留尾部空字符串)
String[] fruits2 = text.split(",", -1);
// 输出: ["apple", "orange", ""] <-- 尾部的空字符串被保留了
// limit = 2 (最多分割1次)
String[] fruits3 = text.split(",", 2);
// 输出: ["apple", "orange,"] <-- 只分割了第一个逗号
与 StringTokenizer 的对比
在早期 Java 版本中,StringTokenizer 也用于分割字符串,但现在,强烈推荐使用 String.split()。
| 特性 | String.split(String regex) |
StringTokenizer |
|---|---|---|
| 分割依据 | 正则表达式 | 单个字符或一组字符 |
| 功能 | 非常强大,支持复杂的分割规则 | 功能简单,不支持正则 |
| 返回值 | 字符串数组 (String[]) |
枚举对象 (Enumeration<String>),需要手动遍历 |
| 性能 | 对于简单分割可能稍慢,但现代JVM优化得很好 | 对于简单分割可能更快,但优势不明显 |
| 灵活性 | 极高 | 低 |
| 推荐度 | 强烈推荐 | 已不推荐,仅用于维护旧代码 |
总结与最佳实践
split()的参数是正则表达式:这是理解其行为的核心。- 转义特殊字符:如果分隔符是 , , 等正则特殊字符,务必用
\\进行转义。 - 处理连续分隔符:使用 或 等量词来匹配一个或多个/零个或多个分隔符,
split("\\s+")或split("\\d+")。 - 处理尾部空字符串:如果你不希望结果数组末尾有空字符串,请使用
split(regex, 0)。 - 优先使用
split():在绝大多数情况下,String.split()是比StringTokenizer更现代、更强大、更灵活的选择。
掌握了这些要点,你就能在 Java 中游刃有余地使用正则表达式进行字符串分割了。
