我的CSV文件中有一行包含一些转义引号:
173,"Yukihiro \"The Ruby Guy\" Matsumoto","Japan"
当我尝试解析Ruby CSV解析器时:
require 'csv'
CSV.foreach('my.csv', headers: true, header_converters: :symbol) do |row|
puts row
end
我收到此错误:
.../1.9.3-p327/lib/ruby/1.9.1/csv.rb:1914:in `block (2 levels) in shift': Missing or stray quote in line 122 (CSV::MalformedCSVError)
如何解决此错误?
答案 0 :(得分:25)
\"
是典型的Unix,而Ruby CSV需要""
解析它:
require 'csv'
text = File.read('test.csv').gsub(/\\"/,'""')
CSV.parse(text, headers: true, header_converters: :symbol) do |row|
puts row
end
注意:如果您的CSV文件非常大,它会使用大量RAM来读取整个文件。考虑一次读取一行文件。
注意:如果您的CSV文件可能在斜杠前面有斜杠,请使用Andrew Grimm的建议来帮助:
gsub(/(?<!\\)\\"/,'""')
答案 1 :(得分:17)
CSV支持“转换器”,我们通常可以使用它来按回字段内容,然后再将其传回我们的代码。例如,可以在一行中的所有字段上使用strip extra spaces。
不幸的是,在将行拆分为字段之后,转换器将启动,并且在该步骤中,CSV对嵌入式引号感到生气,因此我们必须在“行读取”步骤和“解析”之间进行操作。划入字段“step。
这是我的示例CSV文件:
ID,Name,Country
173,"Yukihiro \"The Ruby Guy\" Matsumoto","Japan"
保留你的CSV.foreach
方法,这是我解析它的示例代码,没有CSV生气:
require 'csv'
require 'pp'
header = []
File.foreach('test.csv') do |csv_line|
row = CSV.parse(csv_line.gsub('\"', '""')).first
if header.empty?
header = row.map(&:to_sym)
next
end
row = Hash[header.zip(row)]
pp row
puts row[:Name]
end
结果哈希和名称值:
{:ID=>"173", :Name=>"Yukihiro \"The Ruby Guy\" Matsumoto", :Country=>"Japan"}
Yukihiro "The Ruby Guy" Matsumoto
我认为你想要一个哈希值,因为你指定了:headers
标志:
CSV.foreach('my.csv', headers: true, header_converters: :symbol) do |row|
答案 2 :(得分:-8)
在MSExcel中打开文件并保存为MS-DOS逗号分隔(.csv)