2017-06-22 38 views
2

我正在使用Commons CSV解析与电视节目相关的CSV内容。其中一个节目有一个节目名称,其中包含双引号;使用Commons CSV进行CSV解析 - 引起IOException的引号引用

116,6,2,29 09月10 “” JJ “(60分钟)”, “http://www.tvmaze.com/episodes/4855/criminal-minds-6x02-jj

的showname是 “JJ”(60分钟),这是已经在双引号。这是抛出一个IOException java.io.IOException:(第1行)封装的令牌和分隔符之间的无效字符。

ArrayList<String> allElements = new ArrayList<String>(); 
    CSVFormat csvFormat = CSVFormat.DEFAULT; 
    CSVParser csvFileParser = new CSVParser(new StringReader(line), csvFormat); 

    List<CSVRecord> csvRecords = null; 

    csvRecords = csvFileParser.getRecords(); 

    for (CSVRecord record : csvRecords) { 
     int length = record.size(); 
     for (int x = 0; x < length; x++) { 
      allElements.add(record.get(x)); 
     } 
    } 

    csvFileParser.close(); 
    return allElements; 

CSVFormat.DEFAULT已经设置withQuote( '' “)

我认为这个CSV格式不正确的 ”“ JJ”(60分钟) “应为 ”“, ”JJ“”( 60分钟)“ - 但有没有办法让公共CSV来处理这个问题,或者我需要手动修复这个条目吗?

其他信息:其他显示名称在CSV条目中包含空格和逗号,引用

回答

1

这里的问题是,引号不正确地转义。你的解析器不处理它。尝试univocity-parsers,因为这是java的唯一解析器我知道可以处理引用值内的未转义引号。它比Commons CSV快4倍。试试这个代码:

//configure the parser to handle your situation 
CsvParserSettings settings = new CsvParserSettings(); 
settings.setUnescapedQuoteHandling(STOP_AT_CLOSING_QUOTE); 

//create the parser 
CsvParser parser = new CsvParser(settings); 

//parse your line 
String[] out = parser.parseLine("116,6,2,29 Sep 10,\"\"JJ\" (60 min)\",\"http://www.tvmaze.com/episodes/4855/criminal-minds-6x02-jj\""); 

for(String e : out){ 
    System.out.println(e); 
} 

这将打印:

116 
6 
2 
29 Sep 10 
"JJ" (60 min) 
http://www.tvmaze.com/episodes/4855/criminal-minds-6x02-jj 

希望它能帮助。

披露:我是这个库的作者,它是开源和免费的(Apache 2.0许可)

0

我认为在sa中同时包含引号和空格我的令牌是混淆解析器。试试这个:

CSVFormat csvFormat = CSVFormat.DEFAULT.withQuote('"').withQuote(' '); 

这应该解决它。


对于您的输入线:

String line = "116,6,2,29 Sep 10,\"\"JJ\" (60 min)\",\"http://www.tvmaze.com/episodes/4855/criminal-minds-6x02-jj\""; 

输出是(并且不会引发异常):

[116, 6, 2, 29 Sep 10, ""JJ" (60 min)", "http://www.tvmaze.com/episodes/4855/criminal-minds-6x02-jj"] 
+0

withQuote(““”)已经默认设置不幸的是,空间是合法入境和内遏制。在CSV中的各种其他行在这种方式我不能把它作为一个引号字符 – mhollander38

+0

@ mhollander38空间仍然是我的格式合法,我会添加一个例子和输出 – SHG

0

引用主要允许字段包含分隔符字符。如果字段中的嵌入式引号没有转义,这将无法工作,所以使用引号没有任何意义。如果您的示例值是“JJ”,60分钟,解析器如何知道逗号是该字段的一部分?数据格式不能可靠地处理嵌入式逗号,因此如果您希望能够这样做,最好更改源以生成符合RFC的csv格式。

否则,它看起来像数据源只是用引号包围非数字字段,并将每个字段用逗号分隔,因此解析器需要做相反的处理。您应该将数据作为逗号分隔,并使用removeStart/removeEnd自己去除前导/尾随引号。

您可以使用CSVFormat .withQuote(空),或忘了这一点,只需使用字符串.split(“”)

+0

设置withQuote(null)确实得到然而,IO Exception却传递了不理想的引号,这也意味着像“我爱你,汤米布朗(60分钟)”这样的节目不会像“我爱你并失去其余的名称。在我的问题中,我不清楚许多显示名称是否包含逗号,并且被源代码放在引号内。 – mhollander38

+0

在这种情况下,有什么方法可以调整输入格式吗?如果您想继续使用逗号作为分隔符而不是数据中没有的东西(比如选项卡),但不想生成符合rfc的csv,那么解析器将如何知道如何解析指定的节目:“JJ”,60分钟 – Mic

+0

@mic univocity-parsers是我知道的唯一可以解析这种输入的库,请参阅我的答案。 –