【问题标题】:Ignore double quote in the fields when parsing a CSV file using CSV parser使用 CSV 解析器解析 CSV 文件时忽略字段中的双引号
【发布时间】:2017-01-23 20:48:09
【问题描述】:

样本数据 -

标头1、全名、标头3、标头4

  1. 20, "鲍勃, XXX", "测试", 30
  2. 20, "evan"s,YYY", "test", 30
  3. 20,“汤姆,ZZZ”,“测试”,30

    CSVReader csvReader = new CSVReader(reader, ',', '"');
    

第二行未按预期读取。因为 full_name 列值中有双引号。

我想忽略这种情况。任何建议将不胜感激。

使用 openCSV java api 进行解析。

编辑:

我正在从数据库中获取数据。数据库列字段之一的值中有一个双引号。因此,csv 数据看起来格式不正确。

【问题讨论】:

  • CSV 格式错误。请参阅tools.ietf.org/html/rfc4180,规则 7。如果使用双引号将字段括起来,则出现在字段内的双引号必须通过在其前面加上另一个双引号来进行转义。
  • 不是格式错误,原始数据里面有双引号。 @Guenther
  • 也许 Java Parser with regex 可以帮助你
  • 我需要重写逻辑来解析csv文件。我打算暂时使用任何 csv 阅读器框架。如果没有任何结果,我可能会为它编写自定义解析。感谢@pilkington 的建议

标签: java csv opencsv apache-commons-csv


【解决方案1】:

univocity-parsers 可以处理非转义引号,并且比 opencsv 快 4 倍。试试这个代码:

public static void main(String... args){
    String input = "" +
            "20, \"bob, XXX\", \"test\", 30\n" +
            "20, \"evan\"s,YYY \", \"test\", 30\n" +
            "20, \"Tom, ZZZ\", \"test\", 30 ";


    CsvParserSettings settings = new CsvParserSettings();

    CsvParser parser = new CsvParser(settings);
    List<String[]> rows = parser.parseAll(new StringReader(input));

    //printing values enclosed in [ ]  to make sure you are getting the expected result
    for(String[] row : rows){
        for(String value : row){
            System.out.print("[" + value + "],");

        }
        System.out.println();
    }
}

这将产生:

[20],[bob, XXX],[test],[30],
[20],["evan"s],[YYY "],[test],[30],
[20],[Tom, ZZZ],[test],[30],

此外,您可以通过以下方式之一控制如何处理未转义的引号:

settings.setUnescapedQuoteHandling(UnescapedQuoteHandling.STOP_AT_DELIMITER);
settings.setUnescapedQuoteHandling(UnescapedQuoteHandling.STOP_AT_CLOSING_QUOTE);
settings.setUnescapedQuoteHandling(UnescapedQuoteHandling.RAISE_ERROR);
settings.setUnescapedQuoteHandling(UnescapedQuoteHandling.SKIP_VALUE);

读取大文件时,您可以使用RowProcessor 或像这样遍历每一行:

parser.beginParsing(new File("/path/to/your.csv"));

String[] row;
while ((row = parser.parseNext()) != null) {
    // process row
}

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

【讨论】:

  • 您的解决方案适用于小数据。我正在处理数千行和数百列。这样做可能会增加更多时间。感谢您的建议。
  • 读取数据的方法有很多种。我刚刚发布了一个例子。您可以使用它读取数万亿行和数百 GB 的文件。阅读教程以了解更多信息。
  • 我已经更新了我的答案,以展示如何使用该库来处理大文件。在我的 macbook pro 上完全解析一个包含 300 万行的 100mb 文件大约需要 700 毫秒。希望这会有所帮助
猜你喜欢
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 2011-05-11
  • 2018-05-13
  • 1970-01-01
  • 2019-09-27
相关资源
最近更新 更多