2017-08-31 29 views
0

我在下面的格式解析CSV文件,但除了劃定的數據沒有格式化

PAL : PAL : NF : "INCOME"."Taxable" 
PAL : PAL : NF : "EXPENSES"."TotalExpenses" 
PAL : PAL : NF : "EXPENSES"."Exceptional" 

在java中的數據,我只想來分隔數據,而無需做任何格式,在輸出還援引應該來。我使用下面的代碼時,通常用單義性,

//Simple CSV File Read 
    List<String[]> allRows; 
    try { 
     CsvParserSettings settings = new CsvParserSettings(); 
     settings.getFormat().setLineSeparator("\n"); 
     settings.getFormat().setDelimiter(':'); 

     CsvParser parser = new CsvParser(settings); 
     allRows = parser.parseAll(new FileReader(new File(csvFile))); 
     int i =0, cols=0; 
     for(String[] str:allRows){ 
      i++; 
      cols = str.length; 

      for(String s:str) 
       System.out.print(s+" == "); 

      System.out.println(""); 
      if(i == 10) break; 
     }  
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    }  

輸出就像下面,時段符號的報價,我期待輸出中要像輸入,報價應該來。

PAL == PAL == NF == INCOME"."Taxable 
PAL == PAL == NF == EXPENSES"."TotalExpenses 
PAL == PAL == NF == EXPENSES"."Exceptional 

期望輸出

PAL == PAL == NF == "INCOME"."Taxable" 
PAL == PAL == NF == "EXPENSES"."TotalExpenses" 
PAL == PAL == NF == "EXPENSES"."Exceptional" 
+1

似乎像一個簡單的格式文件閱讀很多工作。爲什麼不使用緩衝讀取器並且執行readLine()。split(「:」)來代替並且完成了? –

+0

適用於我,除了每行的輸出結尾都有一個額外的'=='。但是雙引號都有 – tima

回答

0

這看起來像一個錯誤的代碼中的組合和單義性的CSV規範的放鬆。

輸入是

"INCOME"."Taxable" 

不幸的是,這不是有效的CSV,因爲你有一個包含嵌入式引號的字符串。正確的CSV編碼會一直

"INCOME"".""Taxable" 

單義庫似乎已經不嚴格有關這一點,並猜測輸入的本來是一個字符串(因爲沒有輸入分隔符)在那裏。所以,分析這一領域的內在價值後

​​

這是字符串的實際內容,而沒有被要求做一個字符串在Java中字面外側引號。

然後當你把它寫出來,你忽略了加回周圍的引號,導致你看到的輸出。

摘要:

  1. 單義性處理無效的輸入在符合你要求的方式,這樣你就OK那裏。
  2. 要解決你的問題,你必須放回周圍引號自己

    int field = 0; 
    for(String s:str) { 
        if (++field == 4) 
         System.out.print("\"" + s + "\""); 
        else 
         System.out.print(s + " == "); 
    } 
    

這還修復了額外的尾隨==分隔符的其他漏洞。

+0

謝謝。由於我的實際投入有很多領域,我認爲Univocity可以處理這個問題。 –

+0

默認情況下,庫嘗試從未轉義的引號中「救援」。有一些選項可以處理這些情況,包括'settings.setUnescapedQuoteHandling(RAISE_ERROR);' –

0

爲什麼你不能做這樣的事情,我也測試了結果。請相應地調整您的代碼。

您的數據:

PAL : PAL : NF : "INCOME"."Taxable" 
PAL : PAL : NF : "EXPENSES"."TotalExpenses" 
PAL : PAL : NF : "EXPENSES"."Exceptional" 

代碼:

public static void parseFile(){ 
     String csvFile = "file/User.csv"; 
      String line; 
      try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) { 

       while ((line = br.readLine()) != null) { 
        String equal_string = line.replaceAll(":", "=="); 
        String quoate_string = equal_string.replaceAll("\"\"", "\""); 

        if(quoate_string.startsWith("\"") && quoate_string.endsWith("\"")){ 
         String final_string = quoate_string.substring(1, quoate_string.length()-1); 
         System.out.println(" final : "+final_string); 
        } 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

輸出:

final : PAL == PAL == NF == "INCOME"."Taxable" 
final : PAL == PAL == NF == "EXPENSES"."TotalExpenses" 
final : PAL == PAL == NF == "EXPENSES"."Exceptional" 
+0

:D。謝謝。我也編寫了類似的東西。由於我的輸入有很多字段,我認爲univocity可以處理這個問題。 –

+0

這非常慢。如果這是一個問題,使用圖書館是最好的方式去做。 –

1

作者庫的位置。問題是"INCOME"."Taxable"正在處理爲引用值,並且它將INCOMETaxable之間的引號視爲未轉義的引號。

它將基本上嘗試「拯救」該值並找到結束報價或分隔符(由settings.setUnescapedQuoteHandling(...)確定)。

在您的情況下,最簡單的方法是將您的引用字符設置爲'或甚至\0,如果您的輸入無需處理引用值。有了這個,你應該得到"INCOME"."Taxable"如你所料。

希望這可以幫助

+0

是的,我原本以爲它是一個錯誤,但後來認爲這是一個真正的功能,你在處理異常輸入方面做出了合理的猜測。 +1 –