【问题标题】:How to get rid of extra quotes from the header when using Apache CSVParser使用 Apache CSVParser 时如何去除标题中的多余引号
【发布时间】:2018-07-04 03:32:51
【问题描述】:

我正在尝试提取 CSV 文件来验证预期值。但是,在标题行中读取存在问题。具体来说,无论第一列标题是什么,都会被引用,这会混淆映射。

文件中的读取方法如下:

public boolean openCsv(File fileObject) {
    if (fileObject.exists()) {
        try {
            parser = CSVParser.parse(fileObject, StandardCharsets.UTF_8, CSVFormat.RFC4180.withFirstRecordAsHeader().withIgnoreHeaderCase());
            headers = parser.getHeaderMap();
            records = parser.getRecords();

            return true;
        } catch (IOException e) {
            System.out.println("Cannot parse CSV file: " + fileObject.getName());
        }
    }
    return false;
}

问题是,对于给定的标题:

“公司 ID”、“公司名称”、“公司网站”、“公司电话”、...

标题映射和记录列表将始终保留第一个值:

错误:未找到公司 ID 的 IllegalArgumentException-Mapping,应为 [公司名称、公司电话、公司网站、...、“公司 ID”] 之一

我尝试循环遍历标题并删除引号,但引用的值也是记录映射的一部分,这意味着我必须循环并重建所有内容。

我为 CSVParse.parse 尝试了不同的值,但问题仍然存在。

我有什么遗漏吗?我检查了 Apache Commons JIRA 板,没有其他人报告过这个问题,所以我倾向于认为这是我需要配置的东西。

由于列因导出而异,我无法对它们进行硬编码并将其传递给解析器。它需要是动态的。

【问题讨论】:

  • 从您的错误消息看来,情况正好相反。 Mapping for Company ID not found(公司 ID 周围没有引号); expected one of ... "Company ID"](引用)。所以它期望引用的版本,但得到未引用的版本?
  • @Vasan,请注意,没有其他标题有引号。它只是保留引号的行中的第一个。所以如果我寻找“公司名称”带引号,它会失败。我真的不在乎所有标题是否都有引号,但它必须是一致的。由于可导出的字段是用户配置的,我无法知道第一列的名称。虽然我可能可以用 try/catch 破解一些东西,但 if/else 由于一个异常,它似乎需要做很多工作。
  • 您使用哪个版本的库?您能否向我们展示您使用标头的部分代码? (例如,从行中读取一些字段)
  • 我没有得到相同的结果,没有任何额外的引号适合我。什么代码发出错误消息?我不相信该消息来自 Commons CSV,它必须来自其他代码。请edit您的帖子并包含完整的堆栈跟踪(包括所有引起的部分、代码格式)并准确指出哪个 Java 语句引发了异常。

标签: java csv parsing apache-commons


【解决方案1】:

我能够复制类似的问题,如果“公司 ID”之前有空格,它会被引用(但您可能会注意到标题中第一列之前的空格,而且该空格仍会出现在映射中)。

然后我注意到您的错误消息中还有一件事:“公司 ID”是映射的最后一个打印元素,即使很难,它应该首先使用字母顺序或“文件中”顺序。

接下来我记得 unicode 中有一些“不可见”的字符。例如:zero width space(on wikipedia) 我在“公司 ID”之前创建了零宽度空格的测试文件,并得到了与您在问题中显示的完全相同的错误消息:

未找到公司 ID 的映射,应为 [公司名称、公司电话、公司网站、“公司 ID”] 之一 在 org.apache.commons.csv.CSVRecord.get(CSVRecord.java:102)

上面的消息中没有空格。

顺便说一句,在找到这个之后,我已经复制了您的错误消息并检查了它是否有不可见的字符。 “公司 ID”前似乎有一个"zero width no break space"

您可能必须解析文件并从中删除这些字符 - 我不知道为什么这样的东西会进入 csv 文件。

【讨论】:

  • 可能是 UTF-8 BOM (0xFEFF)
  • @JimGarrison,这将解释它是如何出现的......可能文件是在记事本或其他默认添加它的编辑器中创建的。谢谢指点
  • @JimGarrison 和卡米尔,你们搞定了。生成导出文件的应用程序正在创建一个 UTF-8+BOM 文件。我将解析器切换到Reader reader = new InputStreamReader(new BOMInputStream(new FileInputStream(fileObject)));,它就像一个魅力。谢谢
  • @MivaScott 拯救我的一天,谢谢。当有人找到 BOMInputStream link 的依赖项时
猜你喜欢
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2020-07-31
  • 2021-03-29
  • 1970-01-01
  • 2013-02-06
  • 2012-10-23
相关资源
最近更新 更多