Ruby CSV解析带有转义引号的字符串

时间:2013-01-26 06:32:20

标签: ruby csv

我的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)

如何解决此错误?

3 个答案:

答案 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)