Java Opencsv анализирует CSV с (двойные кавычки в имени) и (запятая в двойных кавычках имени) в CSV-файле - PullRequest
2 голосов
/ 11 ноября 2019

У меня есть данные следующим образом

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), но не могу найти решение для анализа 2-й строки.

Я пытался использовать решения с несколькими ссылками 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 ]

0 голосов
/ 11 ноября 2019

Я думаю, что реальная проблема здесь в том, что ваш CSV-файл не соответствует.

Первая строка данных содержит 10 полей, одно из которых содержит несбалансированную двойную кавычку.

  • Если вы не игнорируете двойные кавычки, то первая строка данных не может быть разобрана.

  • Если вы игнорируете двойные кавычки, то вторая строка данных имеет 11поля.

В основном, первая строка искажена. должен сказать следующее:

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

Не думаю, что есть хороший способ исправить это, кроме отклонения искаженного ввода:

  • Если проблема в неверных данных, попросите человека исправить входной файл (созданный вручную) или источник данных, из которого извлечен входной файл.

  • Если проблема в программе, которая извлекает данные и генерирует CSV, то исправьте , что .

Если вы действительно хотите проанализировать этот вводкак есть, вам нужно будет реализовать собственный синтаксический анализатор CSV вручную для выполнения этой работы. OpenCSV не будет обрабатывать этот ввод, как и любой другой стандартизированный парсер.

0 голосов
/ 11 ноября 2019

У вас просто неправильно сформированный CSV-файл. Согласно RFC-4180 , раздел 2.5

Если поля не заключены в двойные кавычки, то двойные кавычки могут не появляться внутри полей.

и раздел 2.7

Если для заключения полей используются двойные кавычки, то двойная кавычка, появляющаяся внутри поля, должна быть экранирована, предшествуя другой двойной кавычке.

Я посмотрел на этот вопрос , попробуйте заменить все одинарные двойные кавычки на двойные двойные кавычки. И не забудьте обернуть все поля в двойные кавычки.

В вашем примере 99,13863926H,"MAL""COLMHS",ABBOT,1997-04-09,AMKC,RR,RR ,DE, должно работать.

UPD: Хорошо, если выне хочу редактировать вручную, чтобы сделать его RFC-совместимым. Я предлагаю вам запустить это регулярное выражение : ^(?:\d*,[^,]*,)([^"]\w+(?:"\w+)+)(?:,) для вашего файла, чтобы проверить, сколько там неправильных записей.

Вы можетехотите использовать единственную группу захвата для извлечения искаженного имени и правильного экранирования, затем запишите изменения обратно в файл и перечитайте их с выбранным вами анализатором.

...