2017-06-22 57 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是我知道的唯一可以解析這種輸入的庫,請參閱我的答案。 –