【问题标题】:Defining field separator and text qualifier on the fly for CSV file为 CSV 文件动态定义字段分隔符和文本限定符
【发布时间】:2016-07-11 19:27:02
【问题描述】:

我正在读取以逗号(,)作为字段分隔符和双引号(“)作为文本限定符的 csv 文件。以下是获取行列的代码:

row.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")

这工作正常。 但我想动态指定我的字段分隔符和文本限定符,即它们将作为输入与 csv 文件一起传递。并且文件将根据输入文件分隔符和文本限定符进行解析。如何修改上面的正则表达式以即时获取字段分隔符和文本限定符。

编辑: 我正在使用 Apache Commons CSV 来解析 csv 文件。但在我的情况下,标题行可以是文件中的任何行。并且没有办法将标题行索引传递给 Commons CSV 解析器。所以我将手动读取文件并获取标题行。将其列拆分为字符串数组并将其传递给解析器。加上字段分隔符和文本限定符是用户定义的,因此需要在此基础上进行拆分。

【问题讨论】:

  • 为什么不使用 opencsv.sourceforge.net(或任何其他 CSV 库)?如果您真的想使用正则表达式,请参阅Pattern.quote 和其余的字符串连接(例如:row.split(Pattern.quote(";") + "(?=(....))");
  • 考虑使用Commons CSV,您可以在其中定义自定义字段和行分隔符以及引号的用法。事实上,它非常易于使用
  • @SashaSalauyou 我正在使用 Commons CSV 来解析 csv 文件。我需要它来解析文件的标题行(可以是任何行)并将其传递给 Commons CSV,因为无法将标题行索引传递给 Commons CSV 解析器。

标签: java regex csv split


【解决方案1】:

uniVocity-parsers 可以自动检测输入格式以发现要使用的分隔符/引号字符:

    CsvParserSettings settings = new CsvParserSettings(); //many options here, check the tutorial.

    // turns on automatic detection of line separators, 
    // column separators, quotes & quote escapes
    settings.detectFormatAutomatically();

    // configures to skip a number of rows from the input and start parsing from there
    settings.setNumberOfRowsToSkip(3);

    // configures the parser to extract headers from the first parsed row
    settings.setHeaderExtractionEnabled(true);

    CsvParser parser = new CsvParser(settings);
    List<String[]> rows = parser.parseAll(new File("/path/to/your/file.csv"));

免责声明:我是这个库的作者,它是开源免费的(Apache 2.0 许可)

【讨论】:

    【解决方案2】:

    TL;DR:使用 CSV 解析器

    这是唯一正确的答案。解析文件只有一种方法,那就是使用解析器。

    示例用法OpenCSV(无隶属关系,只是我的首选):

    try(final  CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t', '"', '\'')) {
    //                                                ^ your file                ^ delimiter
    //                                                                                 ^ quote
    //                                                                                       ^ escape char
    
    }
    

    与您的正则表达式解决方案不同,这是完全可配置的并支持转义序列。

    【讨论】:

    • 实际上...... OP 不能即时使用 字段分隔符和文本限定符,还有一点格式化/标识不会杀死任何傀儡;)
    • @JordiCastilla “与 csv 文件一起作为输入传递”。这正是 OP 需要的。请重新阅读问题。
    • @JordiCastilla OpenCSV 也支持这一点。 OP 并没有确切说明数据是如何传入的。我认为这完全回答了目前的问题。
    猜你喜欢
    • 2014-04-23
    • 2014-05-28
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多