当前位置: 首页 > 知识库问答 >
问题:

Javaopencsv解析csv与(双引号在名字)和(逗号在双引号名字)列在csv文件

商佑运
2023-03-14

我有如下数据

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

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

因此,使用. with IgnoreQuotations(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,但问题是一样的

共有2个答案

卢阳泽
2023-03-14

你只是有一个格式不正确的csv文件。根据RFC-4180第2.5节

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

第2.7节

如果双引号用于封闭字段,则出现在字段中的双引号必须通过在其前面加上另一个双引号来转义。

我已经查过这个问题了,试着用双引号替换所有单双引号。不要忘记将所有字段包装在双引号中。

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

UPD:好吧,如果您不想手动编辑以使其符合RFC,我建议您对您的文件运行这个正则表达式^(?:\d*,[^,]*,)([^"]\w(?:"\w ) )(?:,)来检查有多少错误记录。

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

乐山
2023-03-14

我认为真正的问题是你的CSV文件不一致。

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

>

如果忽略双引号,则第二个数据行有11个字段。

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

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

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

>

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

    如果问题出在提取数据并生成CSV的程序中,请修复该问题。

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

  •  类似资料:
    • 问题内容: 我正在编写一个Java应用程序以将数据从Oracle导出到CSV文件 不幸的是,数据的内容可能非常棘手。分隔符仍然是逗号,但连续的一些数据可能是这样的: 因此,这是该列上的字符串之一: 我说:“我是5‘10”。 别开玩笑了,我需要在Java生成的CSV文件中的excel或开放式办公室中显示上述注释,而又不能妥协,并且当然不能弄乱其他常规的转义符情况(即,常规的双引号和元组中的常规逗号)

    • 我正在尝试使用OpenCSV解析CSV文件。其中一列以YAML序列化格式存储数据,并被引用,因为其中可以包含逗号。它里面也有引号,所以它通过放两个引号来转义。我能够在Ruby中轻松解析这个文件,但使用OpenCSV我无法完全解析它。这是一个UTF-8编码的文件。 这是我的Java片段,它试图读取文件 这是此文件中的2行。第一行没有被正确解析,并且在处被拆分,因为我猜是转义双引号。

    • 样本数据- Header1,full_name,header3,header4 > 20,“Bob,XXX”,“Test”,30 20,“Evan”s,YYY“,”Test“,30 20,“Tom,ZZZ”,“Test”,30 第二行读起来不像预期的那样。因为full_name列值中有一个双引号。 我想忽略这类案件。任何建议都将不胜感激。 使用openCSV Java api进行解析。 编辑: 我

    • 问题内容: 我有一些输入如下所示: 逗号分隔的值可以是任何顺序。我想用逗号分割字符串;但是,在双引号内包含某些内容的情况下,我需要它既忽略逗号又去除引号(如果可能)。因此,基本上,输出将是以下字符串列表: 我已经看过其他一些答案,并且我认为正则表达式是最好的,但是我想出这些答案很糟糕。 问题答案: 拉瑟是对的。这是一个逗号分隔的值文件,因此您应该使用module。一个简单的例子:

    • 问题内容: 手动编写HTML时,我总是使用单引号。我使用很多渲染的HTML,这些HTML总是使用双引号。这使我可以确定HTML是手工编写的还是生成的。这是一个好主意吗? 两者有什么区别?我知道它们都可以工作,并且得到所有现代浏览器的支持,但是在不同情况下,一个实际上比另一个更好吗? 问题答案: W3组织说: 默认情况下,SGML要求使用双引号(ASCII十进制34)或单引号(ASCII十进制39)