解析制表符分隔文件的策略

时间:2014-03-22 23:46:25

标签: java arrays parsing text-files

在Java中解析制表符分隔文件的最原始方法是什么,以便表格数据不会丢失结构?我正在寻找使用Bean或Jsoup的方法,因为他们对我不熟悉,初学者。我需要有关它背后的逻辑以及有效方法的建议,例如,如果我有一个类似

的表格
ID reference | Identifier    | Type 1| Type 2  | Type 3 |
1            | red#01        | 15%   |  20%    | 10%    |
2            | yellow#08     | 13%   |  20%    | 10%    |

更正:在此示例中,我有类型1 - 3,但我的问题适用于N种类型。

我可以通过仅使用数组来实现表解析,还是Java中有不同的数据结构可以更好地完成此任务?这就是我认为我应该这样做的方式:

  1. 扫描/读取"\t"处的第一行拆分并创建一个String数组。
  2. 将该数组拆分为每个子数组1个表标题的子数组
  3. 然后,开始阅读表格的下一行,并为每个子数组添加列中的相应值。
  4. 这个计划听起来是正确还是我过度复杂/完全错误?有更简单的方法吗? (前提是我还不知道如何将数组拆分成子数组以及如何使用表中的值填充子数组)

3 个答案:

答案 0 :(得分:3)

我会强烈建议您使用读取平面文件解析库,就像优秀的OpenCSV一样。

如果不这样,这是Java 8中的解决方案。

首先,创建一个表示数据的类:

static class Bean {

    private final int id;
    private final String name;
    private final List<Integer> types;

    public Bean(int id, String name, List<Integer> types) {
        this.id = id;
        this.name = name;
        this.types = types;
    }

    //getters 

}

您使用各种列表的建议非常基于脚本。 Java是OO所以你应该利用它来发挥作用。

现在我们只需要解析文件:

public static void main(final String[] args) throws Exception {
    final Path path = Paths.get("path", "to", "file.tsv");
    final List<Bean> parsed;
    try (final Stream<String> lines = Files.lines(path)) {
        parsed = lines.skip(1).map(line -> line.split("\\s*\\|\\s*")).map(line -> {
            final int id = Integer.parseInt(line[0]);
            final String name = line[1];
            final List<Integer> types = Arrays.stream(line).
                    skip(2).map(t -> Integer.parseInt(t.replaceAll("\\D", ""))).
                    collect(Collectors.toList());
            return new Bean(id, name, types);
        }).collect(Collectors.toList());
    }
}

本质上,代码会跳过第一行,然后遍历文件中的行和每行:

  1. 拆分分隔符上的行 - 似乎是|。这需要正则表达式,因此您需要转义管道,因为它是一个特殊字符。我们也会在分隔符之前/之后使用任何空格。
  2. 通过解析数组元素为每一行创建new Bean
  3. 首先将ID解析为int
  4. 接下来得到名字
  5. 最后得到Stream行,跳过前两个元素,然后将剩余部分解析为List<Integer>

答案 1 :(得分:1)

我建议使用Apache Commons CSV包,如主页上所述:http://commons.apache.org/proper/commons-csv/

答案 2 :(得分:0)