2014-03-04 62 views
1

我試圖創建一個轉換器來從CSV輸出中刪除換行符。CSV.generate和轉換器?

我有:

nonewline=lambda do |s| 
    s.gsub(/(\r?\n)+/,' ') 
end 

我已經驗證這正常工作如果我打開一個變量,然後運行是這樣的:

csv=CSV(variable,:converters=>[nonewline]) 

不過,我嘗試使用這段代碼使用CSV.generate來更新一堆預先存在的代碼,但它似乎根本不起作用。

CSV.generate(:converters=>[nonewline]) do |csv| 
    csv << ["hello\ngoodbye"] 
end 

回報:

"\"hello\ngoodbye\"\n" 

我已經嘗試了不少東西,以及嘗試其他的例子,我在網上找到的,它看起來好像與CSV.generate使用時:converters沒有任何效果。

這是正確的,還是有什麼我失蹤?

回答

1

你需要寫你的轉換器如下:

CSV::Converters[:nonewline] = lambda do |s| 
    s.gsub(/(\r?\n)+/,' ') 
end 

然後做:

CSV.generate(:converters => [:nonewline]) do |csv| 
    csv << ["hello\ngoodbye"] 
end 

閱讀文檔Converters

好吧,以上部分我沒有刪除,以告訴你如何編寫自定義CSV轉換器。你寫的方式不正確。

查看CSV::generate

文檔此方法包裝你提供字符串,或空字符串默認,其中被傳遞給設置塊一個CSV對象。您可以使用該塊將CSV行附加到字符串,並在塊退出時返回最終的字符串。

讀完文檔後,很明顯這種方法是寫入一個csv文件,而不是讀取。現在當您正在閱讀CSV文件時,將應用所有轉換器選項(如:converters:header_converters),但在寫入CSV文件時不適用。

讓我告訴你兩個例子來更清楚地說明這一點。

require 'csv' 

string = <<_ 
foo,bar 
baz,quack 
_ 

File.write('a',string) 

CSV::Converters[:upcase] = lambda do |s| 
    s.upcase 
end 

我從CSV文件中讀取數據,所以:converters選項適用於它。

CSV.open('a','r',:converters => :upcase) do |csv| 
    puts csv.read 
end 

輸出

# >> FOO 
# >> BAR 
# >> BAZ 
# >> QUACK 

現在我寫入CSV文件,不應用轉換器選項。

CSV.open('a','w',:converters => :upcase) do |csv| 
    csv << ['dog','cat'] 
end 

CSV.read('a') # => [["dog", "cat"]] 
+0

不幸的是,這是行不通的。我得到了和上面一樣的輸出''\「hello \ ngoodbye \」\ n「' –

+0

@JimMacKenzie根據文檔它應該工作,我正在檢查爲什麼該轉換器沒有運行... –

+0

@JimMacKenzie It在我看來是一個錯誤..如果你告訴我,你的要求,我可以告訴你其他的解決方法,如果有的話。 –

0

嘗試使用:converters刪除換行符不起作用。

我不得不重寫< <方法從csv.rb添加以下代碼到它:

# Change all CR/NL's into one space 
row.map! { |element| 
    if element.is_a?(String) 
    element.gsub(/(\r?\n)+/,' ') 
    else 
    element 
    end 
} 

在線21

我願意放置

output = row.map(&@quote).join(@col_sep) + @row_sep # quote and separate

右前認爲這將是CSV的一個很好的補丁,因爲換行符總是會產生錯誤CSV輸出。