我正在尝试创建一个转换器,以便从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"
我尝试过很多东西以及尝试在网上找到的其他示例,似乎:converters
与CSV.generate
一起使用时没有效果。
这是正确的,还是我缺少的东西?
答案 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
转换器。你写它的方式是不正确的。
此方法将您提供的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输出。