
本文介绍如何准确解析以制表符分隔、包含连续分隔符(如 `\t\t`)的文本行,使空字段不被跳过,推荐使用 `string.split()` 替代已过时且不支持空项保留的 `stringtokenizer`。
StringTokenizer 是 Java 早期提供的字符串分词工具,但它默认忽略所有空令牌(empty tokens)——即遇到连续分隔符(如 \t\t)时,中间的空字段会被直接跳过,无法区分“缺失字段”和“真实空白值”。这导致解析结构化数据(如 TSV 文件)时列数错位、字段错配,严重影响数据完整性。
正确的做法是使用现代、标准且语义清晰的 String.split(String regex, int limit) 方法,并传入负数限制(如 -1),以强制保留末尾及中间的所有空字段:
String[] tokens = line.split("\t", -1); // 关键:-1 表示不限制分割次数,保留所有空项
ArrayList fields = new ArrayList<>(Arrays.asList(tokens));
System.out.println(fields.size() + " >> " + fields); ✅ 示例验证(输入含 \t\t):
若某行为 "R\t900081458\t22222-22-2\t\t\t1\t-1\t1\t0\t0\t1",
则 split("\t", -1) 将返回长度为 11 的数组,其中索引 3 和 4 对应两个空字符串 "",可进一步统一替换为 "BLANK"(按需):
Listal = Arrays.stream(line.split("\t", -1)) .map(s -> s.isEmpty() ? "BLANK" : s) .collect(Collectors.toList()); System.out.println(al.size() + " >> " + al);
⚠️ 注意事项:
- 避免使用 split("\t")(无 limit 参数):它等价于 split("\t", 0),会自动丢弃末尾空字符串,仍可能导致列数不一致;
- StringTokenizer 已被官方标记为 legacy class(见 Javadoc),不推荐用于新项目,尤其不适用于需要精确控制空字段的场景;
- 对于复杂 CSV/TSV 文件(含转义、引号、换行等),建议使用专业库如 OpenCSV 或 Apache Commons CSV,它们能健壮处理边缘情况。
总之,用 String.split("\t", -1) 是解决“连续分隔符→空字段保留”问题最简洁、可靠、符合 Java 最佳实践的方案。
立即学习“Java免费学习笔记(深入)”;










