杰瑞科技汇

Java字符串分隔符如何正确使用?

String.split()

这是将一个字符串根据指定的分隔符(或正则表达式)拆分成一个字符串数组 (String[]) 的最直接方法。

Java字符串分隔符如何正确使用?-图1
(图片来源网络,侵删)

基本语法

public String[] split(String regex)
  • regex: 分隔符。注意:这里是一个正则表达式,而不仅仅是普通字符。

示例 1:使用普通字符作为分隔符

当分隔符是简单的字符(如 , , , 空格等)时,split() 的行为非常直观。

String sentence = "apple,banana,orange,grape";
String[] fruits = sentence.split(",");
// 输出结果
for (String fruit : fruits) {
    System.out.println(fruit);
}
// 输出:
// apple
// banana
// orange
// grape

示例 2:使用多个字符作为分隔符

分隔符可以是多个字符组成的字符串。

String data = "apple-+-banana-+-orange";
String[] items = data.split("-+-");
for (String item : items) {
    System.out.println(item);
}
// 输出:
// apple
// banana
// orange

示例 3:使用正则表达式作为分隔符

这是 split() 功能强大的地方,但也容易出错,当分隔符本身是正则表达式的特殊字符时,必须进行转义。

常见的正则元字符: , , , , , ^, , , , [, , \, ],

Java字符串分隔符如何正确使用?-图2
(图片来源网络,侵删)

错误示范: 你想用 作为分隔符,但 在正则中表示“任意字符”,所以结果可能不是你想要的。

String ip = "192.168.1.1";
// 错误写法: "." 匹配任意字符,会得到 ["", "", "", "", "", "1"]
String[] parts1 = ip.split("."); 
// 输出可能是一个很长的数组,因为 "192" 会被拆分成 ["1", "9", "2", ...]
// 正确写法: 使用 "\\" 对 "." 进行转义
String[] parts2 = ip.split("\\.");
for (String part : parts2) {
    System.out.println(part);
}
// 输出:
// 192
// 168
// 1
// 1

转义规则: 在 Java 字符串中,一个反斜杠 \ 是一个转义字符,要在字符串中表示一个字面上的反斜杠 \,你需要写成 \\,而正则表达式中的转义也是用 \,要表示一个正则表达式的转义字符(如 \.),在 Java 字符串中你需要写成 "\\\\"

另一个例子:用 分隔 在正则中表示“或”。

String choices = "A|B|C|D";
// 错误写法: "|" 会被当作 "或" 操作符
String[] options1 = choices.split("|"); 
// 输出: ["", "", "", "", "A", "|", "B", "|", "C", "|", "D"] (结果很奇怪)
// 正确写法: 对 "|" 进行转义
String[] options2 = choices.split("\\|");
for (String option : options2) {
    System.out.println(option);
}
// 输出:
// A
// B
// C
// D

split() 的高级用法:限制分割次数

split() 方法还有一个重载版本,可以指定分割的最大次数。

Java字符串分隔符如何正确使用?-图3
(图片来源网络,侵删)
public String[] split(String regex, int limit)
  • limit: 分割的次数限制。
    • limit > 0: 最多分割 limit - 1 次,数组的长度不会超过 limit
    • limit < 0: 分割次数没有限制,与 split(regex) 相同。
    • limit == 0: 分割次数没有限制,并且会忽略末尾的空字符串,这是与 limit < 0 的一个关键区别。

示例 4:使用 limit 参数

String csvLine = "a,b,c,,d,"; // 注意末尾的逗号
// limit > 0, 3
String[] parts1 = csvLine.split(",", 3);
// 只分割前2个逗号,剩余部分作为一个整体
// 结果: ["a", "b", "c,,d,"]
System.out.println("Limit=3: " + Arrays.toString(parts1));
// limit < 0, -1
String[] parts2 = csvLine.split(",", -1);
// 完全分割,保留所有空字符串
// 结果: ["a", "b", "c", "", "d", ""]
System.out.println("Limit=-1: " + Arrays.toString(parts2));
// limit = 0
String[] parts3 = csvLine.split(",", 0);
// 完全分割,但忽略末尾的空字符串
// 结果: ["a", "b", "c", "", "d"]
System.out.println("Limit=0: " + Arrays.toString(parts3));

相关方法:StringTokenizer

这是一个更老、更底层的类,在处理简单分隔符时比 split() 性能可能更好,但功能较弱,且被认为是遗留类。

  • 特点:
    • 默认分隔符是空白字符(空格、制表符、换行、回车)。
    • 不能使用正则表达式。
    • 默认会忽略连续的分隔符和前后的分隔符(不像 split() 会保留空字符串)。
import java.util.StringTokenizer;
String text = "  apple, banana,  orange,  ";
StringTokenizer tokenizer = new StringTokenizer(text, ","); // 使用逗号作为分隔符
while (tokenizer.hasMoreTokens()) {
    System.out.println(tokenizer.nextToken());
}
// 输出 (自动去除了前后和中间多余的空格):
// apple
//  banana
//  orange

推荐: 在新代码中,除非有性能瓶颈或特殊需求,否则优先使用 String.split(),因为它更符合现代 Java 的编程风格,功能也更强大。


使用 Java 8 Stream API 进行分割

对于更复杂的场景,比如分割后需要立即进行过滤或转换,可以使用 Stream API。

import java.util.Arrays;
import java.util.stream.Collectors;
String data = "1,2,3,empty,4,5,";
// 1. 分割
// 2. 过滤掉 "empty" 字符串和 null
// 3. 将字符串转换为整数
// 4. 收集到一个 List 中
List<Integer> numbers = Arrays.stream(data.split(","))
                               .map(String::trim) // 去除每个元素两端的空格
                               .filter(s -> !"empty".equals(s) && !s.isEmpty()) // 过滤
                               .map(Integer::parseInt) // 转换
                               .collect(Collectors.toList());
System.out.println(numbers); // 输出: [1, 2, 3, 4, 5]

总结与最佳实践

方法 优点 缺点 适用场景
String.split() 功能强大,支持正则表达式,语法简洁,是标准做法。 分隔符是正则表达式,特殊字符需要转义,可能产生空字符串。 绝大多数情况下的首选
StringTokenizer 性能可能稍好,对于简单分隔符处理直观。 功能有限(不支持正则),是遗留类,API 较旧。 简单、性能敏感的场景,或维护旧代码。
Stream API 极其灵活,可以无缝衔接后续的过滤、映射、聚合等操作。 语法相对复杂,对于简单分割有点“杀鸡用牛刀”。 需要在分割后立即进行复杂处理的流式操作。

最佳实践建议:

  1. 首选 String.split():这是最通用、最符合现代 Java 编程习惯的方法。
  2. 记住转义:如果你的分隔符是 , , 等正则元字符,一定要记得用 \\ 进行转义,split("\\.")
  3. 处理空字符串split() 总是会保留由连续分隔符产生的空字符串,如果你需要忽略它们,可以在 split 后手动过滤,或者使用 split(regex, 0) 来自动忽略末尾的空字符串。
  4. 复杂操作用 Stream:如果分割只是数据处理的第一步,后面跟着过滤、转换等,直接使用 Arrays.stream(split(...)) 会非常方便。
分享:
扫描分享到社交APP
上一篇
下一篇