2017-09-14 55 views
2

我有CSV與像一些一行:如何在ruby中使用奇怪的引號讀取CSV?

col1,col "two",col3 

,所以我得到Illegal quoting錯誤並修復,通過設置:quote_char => "\x00"

["col1", "col\"two\"", "col3"] 

但像

col1,col2,"col,3" 

後線在那個文件中

["col1", "col2", "\"col", "3\""] 

然後我一行一行地讀取文件,並調用parse_csv包裝在塊中。設置:quote_char => "\""rescueCSV::MalformedCSVError例外和針對特定行設置:quote_char => "\x00"retry

所有作品完美,直到我們在這種情況下,從例外它rescue小號獲得線

col1,col "two","col,3" 

,設置:quote_char => "\x00"和結果是

["col1", "col\"two\"", "\"col", "3\""] 

Apple Numbers能夠完全正確地打開該文件。

parse_csv是否有任何設置來處理這個沒有預處理字符串的方式?

UPD我顯示CSV行,因爲它是在p打印文件和結果(數組)。我的字符串中沒有實際的\"

回答

1

這是一個無效csv文件。如果你有機會獲得源代碼,你可以(問)生成數據如下:

col1,"col ""two""","col,3" 

如果沒有,唯一的選擇是自己分析數據:

pseudocode: 

while(read_line) { 

    bool InsideQuotes = false 
    for each_char_in_line { 

     if(char == doublequote) 
      InsideQuotes = !InsideQuotes 

     if(char == ',' and !InsideQuotes) 
      // separator found - process field 
    } 
} 

這也將請照顧col1,"col ""two""","col,3"之類的轉義報價。

如果文件包含多行字段,則需要完成一些工作。

+0

不幸的是,我不能訪問源代碼,我認爲char這樣的字符處理會導致巨大的性能損失,這部分代碼處理大的CSV文件(數百萬條記錄) – Yaroslav

+1

@雅羅斯拉夫那麼,讓我們希望沒有字段像',24「監視器,'在該文件:) –

+0

@Yaroslav關於性能:我不知道Ruby或它的性能,但我想如果行可以被視爲數組不會那麼糟糕。 C/C++中的相同算法實際上比標準解析器更快。也許你可以檢查Ruby是否支持內存映射文件,這也可以不需要readline(將字符串複製到緩衝區中)。 –

1

CSV並不是一個標準,更多的是大家認爲他們用來正確描述他們古怪格式的名稱,儘管他們是RFC standard for CSV,但這只是另一件沒有人關注的事情。

因此,很多讀CSV的程序都非常寬容。 Ruby的核心CSV庫非常好,但不像其他人那樣具有適應性。那是因爲你在那裏得到了Ruby,讓你擺脫困境,而在Numbers中卻沒有。

嘗試改寫\""",其是常規的CSV格式,如在上述聯的規範中定義:

CSV.parse(File.read.gsub(/\\"/, '""')) 
+0

對不起,但我顯示CSV行,因爲它是在文件和結果(數組),因爲它是由'p'打印。在我的字符串中沒有實際的'\'' – Yaroslav

相關問題