17

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)

このエラーを回避するにはどうすればよいですか?

4

3 に答える 3

27

これ\"は典型的な 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 が使用されます。一度に 1 行ずつファイルを読み取ることを検討してください。

注: CSV ファイルのスラッシュの前にスラッシュが含まれている可能性がある場合は、以下の Andrew Grimm の提案を参考にしてください。

gsub(/(?<!\\)\\"/,'""')
于 2013-01-26T06:50:19.483 に答える
17

CSV は「コンバーター」をサポートします。これは通常、フィールドのコンテンツをコードに戻す前にメッセージを送信するために使用できます。たとえば、行内のすべてのフィールドで余分なスペースを削除するために使用できます。

残念ながら、行がフィールドに分割された後にコンバーターが起動し、CSV が埋め込まれた引用符について怒っているのはそのステップの間です。 " ステップ。

これは私のサンプル 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|
于 2013-01-26T18:28:19.957 に答える
-10

MSExcel でファイルを開き、MS-DOS カンマ区切り (.csv) として保存します。

于 2016-01-12T03:19:49.067 に答える