CSVファイルを解析しようとするとエラーメッセージが表示される引用符で囲まれていないフィールドでは、\ rまたは\ n(2行目)は許可されません。。
私はここSO類似のトピックで見つけました、ここで以下を行うためのヒントがありました:
CSV.open('file.csv', :row_sep => "\r\n") do |csv|
しかし、残念ながら彼はうまくいきません... CSVファイルを変更できないので、コードで修正する必要があります。
[〜#〜] edit [〜#〜] CSVファイルのサンプル:
A;B;C
1234;...
それを行う方法はありますか?
どうもありがとう!
まず、列区切り文字を ';'に設定する必要があります。これは、CSVファイルが解析される通常の方法ではないためです。これは私のために働きました:
CSV.open('file.csv', :row_sep => :auto, :col_sep => ";") do |csv|
csv.each { |a,b,c| puts "#{a},#{b},#{c}" }
end
1.9.2 CSVドキュメントから:
自動検出は、データを先読みして、次の
\r\n
、\n
、または\r
シーケンスを探します。シーケンスは、引用符で囲まれたフィールドで発生しても選択されます。ただし、そこでは同じ行末があると仮定します。
奇妙なフォーマットを使用している可能性のあるプログラム(Excelやスプレッドシートなど)によってCSVが変更または保存された場合のより簡単な解決策:
私にとってはLinkedIn CSVをインポートしていてエラーが発生しました。
次のように空白行を削除しました:
def import
csv_text = File.read('filepath', :encoding => 'ISO-8859-1')
#remove blank lines from LinkedIn
csv_text = csv_text.gsub /^$\n/, ''
@csv = CSV.parse(csv_text, :headers => true, skip_blanks: true)
end
私はこれが古い投稿であることを理解していますが、最近、標準のRuby CSVライブラリで解析できない、不適切にフォーマットされたCSVファイルで同様の問題が発生しました。
すぐにファイルを解析する SmarterCSV gemを試しました。これは外部ライブラリなので、誰にとっても最善の解決策とは言えないかもしれませんが、自分でファイルを解析するよりも優れています。
opts = { col_sep: ';', file_encoding: 'iso-8859-1', skip_lines: 5 }
SmarterCSV.process(file, opts).each do |row|
p row[:someheader]
end
私の場合、エンコーディングと、データ内で発生しないことが保証されている引用文字を提供する必要がありました
CSV.read("file.txt", 'rb:bom|UTF-16LE', {:row_sep => "\r\n", :col_sep => "\t", :quote_char => "\x00"})
セルに改行が含まれるExcelからのファイルを処理する必要がある場合は、解決策もあります。
この方法の大きな欠点は、文字列にセミコロンや二重引用符を使用できないことです。
私はセミコロンなしで行くことを選択します
if file.respond_to?(:read)
csv_contents = file.read
elsif file_data.respond_to?(:path)
csv_contents = File.read(file.path)
else
logger.error "Bad file_data: #{file_data.class.name}: #{file_data.inspect}"
return false
end
result = "string"
csv_contents = csv_contents.force_encoding("iso-8859-1").encode('utf-8') # In my case the files are latin 1...
# Here is the important part (Remove all newlines between quotes):
while !result.nil?
result = csv_contents.sub!(/(\"[^\;]*)[\n\r]([^\;]*\")/){$1 + ", " + $2}
end
CSV.parse(csv_contents, headers: false, :row_sep => :auto, col_sep: ";") do |row|
# do whatever
end
私にとって、このソリューションは問題なく機能します。大きなファイルを扱う場合、問題が発生する可能性があります。
引用符なしで移動したい場合は、正規表現のセミコロンを引用符に置き換えてください。