
本文介绍在 java 中解析以制表符分隔的文本行时,如何准确识别并保留连续分隔符之间的空字段,替代已不推荐的 `stringtokenizer`,推荐使用 `string.split()` 或专业 csv 解析库。
StringTokenizer 是 Java 早期提供的字符串分割工具,但它默认跳过所有分隔符之间的空字符串——即遇到连续分隔符(如 \t\t)时,它不会生成空 token,导致字段数量丢失、位置错位。这在处理结构化数据(如 TSV 文件)时极易引发逻辑错误,尤其当字段顺序敏感(如数据库导入、ETL 处理)时。
✅ 正确做法:使用 String.split(String regex, int limit) 并指定负数 limit 参数:
String[] tokens = line.split("\t", -1); // 关键:-1 表示不限制分割次数,保留末尾及中间的空字符串
ArrayList fields = new ArrayList<>(Arrays.asList(tokens));
System.out.println(fields.size() + " >> " + fields); ? 说明:split("\t", -1) 会将 "A\t\tB" 拆分为 ["A", "", "B"](3 个元素),而 split("\t")(等价于 split("\t", 0))会忽略尾部空串且合并连续分隔符,结果为 ["A", "B"](2 个元素)。
? 示例验证(模拟含双制表符的输入):
String line = "R\t900081458\t22222-22-2\t\t\t1\t-1\t1\t0\t0\t1";
String[] tokens = line.split("\t", -1);
System.out.println(tokens.length); // 输出:11
System.out.println(Arrays.toString(tokens));
// 输出:[R, 900081458, 22222-22-2, "", "", 1, -1, 1, 0, 0, 1]⚠️ 注意事项:
- split() 基于正则表达式,若分隔符含特殊字符(如 .、*、+),需转义(\t 本身无需转义);
- StringTokenizer 已被官方标记为 legacy class(JDK 文档明确建议优先使用 String.split() 或 java.util.Scanner);
- 若文件格式复杂(含引号包裹、换行符嵌入、转义字符等),强烈推荐使用成熟库如 OpenCSV(支持自定义分隔符、空值处理、类型转换)或 Apache Commons CSV。
? 进阶建议:
对于生产级数据解析,避免手动拼接逻辑。例如使用 OpenCSV 解析制表符分隔文件:
CSVParser parser = new CSVParserBuilder()
.withSeparator('\t')
.withIgnoreEmptyLines(false)
.withIgnoreSurroundingSpaces(true)
.build();
List records = parser.parseAll(new FileReader("data.dat")); 综上,解决“连续分隔符产生空字段”问题的核心在于:弃用 StringTokenizer,改用 String.split(regex, -1) 确保语义完整;复杂场景交由专业 CSV 库处理,兼顾健壮性与可维护性。










