【问题标题】:Java Opencsv parse csv with (double quotes in first name) and (comma in double quoted first name) column in csv fileJava Opencsv 使用 csv 文件中的(名字中的双引号)和(双引号中的名字中的逗号)列解析 csv
【发布时间】:2020-03-07 01:28:50
【问题描述】:

我有如下数据

ID1,ID2,FIRST_NAME,LAST_NAME,BIRTH_DATE,HA1,HA2,HA3,STATUS,DT
99,13863926H,MAL"COLMHS,ABBOT,1997-04-09,AMKC,RR,RR  ,DE,
89,12973388H,"SAGAR,TARLE",ABDAT,1997-11-02,RNDC,RR,RR  ,DE,
71,88JunkTest,Howdy,Doody,1985-11-02,RNDC,HA,HACLASSTYPE  ,DE,2019-12-25

我正在尝试使用打开的 CSV 解析 csv,其中我的 CSV 名字可以包含双引号 (MAL"COLMHS) 或带逗号的双引号 ("SAGAR,TARLE") 或不带双引号的名字。

所以使用 .withIgnoreQuotations(true) 我可以解析第一行 (MAL"COLMHS) 但无法找到解析第二行的解决方案。

我尝试了具有多个 StackOverflow 链接的解决方案,但无法解决它们。

我知道我的 CSV 文件不一致,但来自客户端的 CSV 文件中存在太多此类记录,并且很难手动使其保持一致,因此尝试搜索自动化解决方案。

 List<Results> beans = new CsvToBeanBuilder<Results>(new FileReader(file.getAbsolutePath()))
                            .withType(Results.class)
                            .withIgnoreQuotations(true)
                            .build().parse();

错误

java.lang.RuntimeException: Error parsing CSV line: 3. [3491903139,12973388H,SAGAR,TARLE,ABDAT,1997-11-02,RNDC,RR,RR  ,DE,]
    at com.opencsv.bean.CsvToBean.parse(CsvToBean.java:366)
    at com.apds.partner.nycdoc.main.NycDocApplication.main(NycDocApplication.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: com.opencsv.exceptions.CsvRequiredFieldEmptyException: Number of data fields does not match number of headers.
    at com.opencsv.bean.HeaderColumnNameMappingStrategy.verifyLineLength(HeaderColumnNameMappingStrategy.java:110)
    at com.opencsv.bean.AbstractMappingStrategy.populateNewBean(AbstractMappingStrategy.java:313)
    at com.opencsv.bean.concurrent.ProcessCsvLine.processLine(ProcessCsvLine.java:132)
    at com.opencsv.bean.concurrent.ProcessCsvLine.run(ProcessCsvLine.java:85)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
*****

编辑: 我也试过 SuperCSV 但同样的问题

【问题讨论】:

  • 您应该发布您尝试过的代码,以便我们知道哪里出错了
  • 请检查更新后的代码
  • 所以“SAGAR,TARLE”会被解析为 FIRST_NAME,值为 SAGAR,TARLE?让我知道我的理解是否正确。
  • 您需要修复您的 csv。您不能忽略双引号并同时使用它们将字段括起来。
  • @hagarwal 是的,“SAGAR,TARLE”将被解析为 FIRST_NAME,其值为 SAGAR、TARLE 或

标签: java csv parsing pojo opencsv


【解决方案1】:

我认为这里真正的问题是您的 CSV 文件不符合要求。

第一个数据行有 10 个字段,其中一个包含不平衡的双引号。

  • 如果不忽略双引号,则第一行数据不可解析。

  • 如果您确实忽略了双引号,那么第二个数据行有 11 个字段。

基本上,第一行格式错误。它应该这样说:

 99,13863926H,"MAL""COLMHS",ABBOT,1997-04-09,AMKC,RR,RR  ,DE,

我认为除了拒绝格式错误的输入之外,没有什么好的方法可以解决这个问题:

  • 如果问题是错误数据,请人修复(手工创建的)输入文件或从中提取输入文件的数据源。

  • 如果问题出在提取数据和生成 CSV 的程序中,请修复那个

如果您真的想按原样解析此输入,则需要手动实现自己的 CSV 解析器来完成这项工作。 OpenCSV 不会处理这个输入,任何其他基于标准的解析器也不会。

【讨论】:

    【解决方案2】:

    您只有一个格式错误的 csv 文件。根据RFC-4180,第 2.5 节

    如果字段没有用双引号括起来,则可以使用双引号 不会出现在字段内。

    和第 2.7 节

    如果使用双引号将字段括起来,则使用双引号 出现在一个字段中必须通过在它前面加上另一个来转义 双引号。

    我查过this question,尝试用双双引号替换所有单双引号。并且不要忘记将所有字段包含在双引号内。

    在您的示例中,99,13863926H,"MAL""COLMHS",ABBOT,1997-04-09,AMKC,RR,RR ,DE, 应该可以工作。

    UPD:好吧,如果您不想手动编辑以使其符合 RFC,我建议您针对您的文件 running this regex:^(?:\d*,[^,]*,)([^"]\w+(?:"\w+)+)(?:,) 检查那里有多少错误记录是。

    您可能希望使用唯一的捕获组来提取格式错误的名称并将其正确转义,然后将更改写回文件并使用您选择的解析器重新读取它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      相关资源
      最近更新 更多