【问题标题】:Ruby CSV - Illegal quoting in line 1. CSV::MalformedCSVErrorRuby CSV - 第 1 行的非法引用。CSV::MalformedCSVError
【发布时间】:2014-08-10 20:29:41
【问题描述】:

我在读取 csv 文件时遇到问题。文件来自 Windows,所以我想有一些编码问题。我的代码如下所示:

CSV.open(path, 'w', headers: :first_row, col_sep: ';', row_sep: "\r\n", encoding: 'utf-8') do |csv|    
    CSV.parse(open(doc.file.url), headers: :first_row, col_sep: ';', quote_char: "\"", row_sep: "\r\n", encoding: 'utf-8').each_with_index do |line, index| 

        csv << line.headers if index == 0

        # do something wiht row

        csv << line 
    end
end

我必须打开现有文件并从中完成一些列。所以我只是创建新文件。现有文件存储在 Dropbox 上,所以我必须使用 open 方法。

问题是我在这一行得到一个错误:

 CSV.parse(open(doc.file.url), headers: :first_row, col_sep: ';', quote_char: "\"", row_sep: "\r\n", encoding: 'utf-8').each_with_index do |line, index| 

错误是:

  Illegal quoting in line 1. CSV::MalformedCSVError

我检查了一下,似乎文件中没有 BOM 字符(不确定检查是否正确)。问题似乎出在引号字符中。文件中的每一行都会引发异常。

这是给我带来问题的文件:https://dl.dropboxusercontent.com/u/3900955/geo_bez_adresu_10_do_testow_small.csv

我尝试了 StackOverflow 的不同方法,但没有任何帮助,例如我将代码更改为:

CSV.open(path, 'w', headers: :first_row, col_sep: ';', row_sep: "\r\n", encoding: 'utf-8') do |csv|
    open(doc.file.url) do |f|
        f.each_line do |line|
            CSV.parse(line, 'r:bom|utf-8') do |row|
               csv << row
            end
        end
    end
end 

但这无济于事。对于解析此文件的任何帮助,我将不胜感激。

=======编辑=========

当我在 Windows 上使用 ANSI 编码为 UTF-8(在 Notepad++ 中)保护同一个文件时,我可以正确解析文件。从这个讨论What is "ANSI as UTF-8" and how can I make fputcsv() generate UTF-8 w/BOM?,看来我在原始文件中有BOM。如果我的文件带有 BOM,我如何签入 Ruby,以及如何使用 BOM 解析 csv 文件?

【问题讨论】:

  • 您使用的是旧版本的 ruby​​ 吗?
  • 不,我使用的是 Ruby 2.1.2p95。

标签: ruby csv


【解决方案1】:

CSV.parse() 在它的第一个参数上需要一个字符串,但你传递的是一个 File 对象。发生的情况是 parse() 会解析 (file object).to_s 的扩展值并导致错误。

更新

要使用 BOM 读取文件,您可以这样做:

CSV.new(File.open('file.csv', 'r:bom|utf-8'), col_sep: ';').each do |row|
  ...
end

参考:https://stackoverflow.com/a/7780559/445221

【讨论】:

  • 是的,我在 SO 上看到了这个帖子,但是我不能使用 File.open,因为正如我所说的文件是远程的,所以我需要使用 open 方法。当我更改代码时:CSV.new(open(doc.file.url, 'r:bom|utf-8')..... 我收到一个错误:“未知编码名称 - bom|utf-8”。那么如何为 URI.open 方法设置带有编码的 UTF-8 呢?
【解决方案2】:

如果远程文件包含 BOM,我没有找到任何直接读取远程文件的方法。所以我使用 Tempfile 文件创建临时文件,然后使用 'r:bom|utf-8' 执行 CSV.open:

doc = Document.find(doc_id)

path = "#{Rails.root.join('tmp')}/#{doc.name.split('.').first}_#{Time.now.to_i}.csv"

file = Tempfile.new(["#{doc.name.split('.').first}_#{Time.now.to_i}", '.csv']) 
file.binmode
file << open(doc.file.url).read
file.close

CSV.open(path, 'w', headers: :first_row, col_sep: ';', row_sep: "\r\n", encoding: 'utf-8') do |csv|
    CSV.open(file.path, 'r:bom|utf-8', headers: :first_row, col_sep: ';', quote_char: "\"", row_sep: "\r\n").each_with_index do |line, index| 

    # do something

    end
end 

现在,它似乎解析了文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    相关资源
    最近更新 更多