杰瑞科技汇

Java split分割字符串时如何处理特殊字符?

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

Java split分割字符串时如何处理特殊字符?-图1
(图片来源网络,侵删)

基本语法

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);
}

输出:

Java split分割字符串时如何处理特殊字符?-图2
(图片来源网络,侵删)
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 == 0limit < 0 在大多数情况下行为相同,但有一个关键区别:它会丢弃结果末尾的空字符串。

Java split分割字符串时如何处理特殊字符?-图3
(图片来源网络,侵删)
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()


最佳实践总结

  1. 永远记住 regex 是正则表达式:如果分隔符是 , , , , , , , , [, , \ 等特殊字符,必须使用 \\ 进行转义
  2. 处理空白字符:分割空格、制表符等时,使用 \\s+ 来匹配一个或多个连续的空白字符,避免产生空字符串。
  3. 了解 limit 参数:当你只需要分割字符串的前几部分时,使用 limit > 0 可以提高效率并简化逻辑。
  4. 警惕末尾的空字符串:如果字符串末尾有分隔符,split 会产生空字符串,如果不需要这些空字符串,可以使用 split(regex, 0)
  5. 优先使用 split():在现代 Java 开发中,String.split() 是功能最强大、最灵活的字符串分割工具。
分享:
扫描分享到社交APP
上一篇
下一篇