CSV.generate和转换器?

时间:2014-03-04 18:05:02

标签: ruby csv

我正在尝试创建一个转换器,以便从CSV输出中删除换行符。

我有:

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"

我尝试过很多东西以及尝试在网上找到的其他示例,似乎:convertersCSV.generate一起使用时没有效果。

这是正确的,还是我缺少的东西?

2 个答案:

答案 0 :(得分: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

的文档
  

此方法将您提供的String或空的默认String包装在传递给提供的块的CSV对象中。您可以使用该块将CSV行附加到String,当块退出时,将返回最终的String。

阅读完文档之后,很明显这个方法是用于写入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"]]

答案 1 :(得分:0)

尝试使用:converters删除换行符无效。

我不得不重写&lt;&lt;从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
}

放在

之前

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

第21行。

我认为这将是CSV的一个很好的补丁,因为换行总是会产生错误的CSV输出。