如何在 Rails 中解析 CSV 期间更改编码

Posted

技术标签:

【中文标题】如何在 Rails 中解析 CSV 期间更改编码【英文标题】:How to change the encoding during CSV parsing in Rails 【发布时间】:2011-10-28 01:59:35 【问题描述】:

我想知道在导入和解析 CSV 文件时如何更改它的编码。我有这个代码:

csv = CSV.parse(output, :headers => true, :col_sep => ";")
csv.each do |row|
  row = row.to_hash.with_indifferent_access
  insert_data_method(row)
end

当我阅读我的文件时,我收到了这个错误:

Encoding::CompatibilityError in FileImportingController#load_file
incompatible character encodings: ASCII-8BIT and UTF-8

我读到了row.force_encoding('utf-8'),但它不起作用:

NoMethodError in FileImportingController#load_file
undefined method `force_encoding' for #<ActiveSupport::HashWithIndifferentAccess:0x2905ad0>

谢谢。

【问题讨论】:

是否可以添加一个间接步骤并输出单独的文件,而不是将其转换为不同的编码?例如,文本文件在某些​​部分编码为 UTF-8,但在其他部分编码为 UTF-16LE。只要标题相同,就将一个文件输出到 filename_utf8.txt,将另一个文件输出到 filename_utf16le.txt。这种方式可能使不强制编码成为可能。 【参考方案1】:

我必须阅读以 ISO-8859-1 编码的 CSV 文件。 做有据可查

CSV.foreach(filename, encoding:'iso-8859-1:utf-8', col_sep: ';', headers: true) do |row|

抛出异常

ArgumentError: invalid byte sequence in UTF-8
    from csv.rb:2027:in '=~' 
    from csv.rb:2027:in 'init_separators' 
    from csv.rb:1570:in 'initialize' 
    from csv.rb:1335:in 'new' 
    from csv.rb:1335:in 'open' 
    from csv.rb:1201:in 'foreach'

所以我最终读取了文件并在读取时将其转换为 UTF-8,然后解析字符串:

CSV.parse(File.open(filename, 'r:iso-8859-1:utf-8')|f| f.read, col_sep: ';', headers: true, header_converters: :symbol) do |row|
    pp row
end

【讨论】:

【参考方案2】:

force_encoding 旨在在字符串上运行,但看起来您是在哈希上调用它。你可以说:

output.force_encoding('utf-8')
csv = CSV.parse(output, :headers => true, :col_sep => ";")
...

【讨论】:

我刚试过。我收到此错误:ArgumentError in FileImportingController#load_fileinvalid byte sequence in UTF-8 尝试运行它:Iconv.conv('utf-8//IGNORE','utf-8',output) 不幸的是,我得到了那个错误:Encoding::CompatibilityError in FileImportingController#load_fileincompatible character encodings: ASCII-8BIT and UTF-8 我假设您并不真正关心更改编码类型,您的目标是解析文件。你从哪里加载你的字符串?也许可以采取另一种方法。 我正在从 CSV 文件加载它。现在可以了,我直接从文件中更改了编码。【参考方案3】:

嘿,我写了一点blog post 关于我所做的事情,但它比已经发布的内容稍微冗长。无论出于何种原因,我无法让这些解决方案发挥作用,但确实如此。

这个要点是我只需替换(或在我的情况下,删除)文件中的无效/未定义字符,然后重写它。我使用这种方法来转换文件:

def convert_to_utf8_encoding(original_file)  
  original_string = original_file.read
  final_string = original_string.encode(invalid: :replace, undef: :replace, replace: '') #If you'd rather invalid characters be replaced with something else, do so here.
  final_file = Tempfile.new('import') #No need to save a real File
  final_file.write(final_string)
  final_file.close #Don't forget me
  final_file
end 

希望这会有所帮助。

编辑:此处未指定目标编码,因为 encode 假定您正在编码为默认编码,对于大多数 Rails 应用程序来说,默认编码是 UTF-8(我相信)

【讨论】:

获取字符串并使用“编码”删除无效和未定义的字符对我有用。完美,谢谢!

以上是关于如何在 Rails 中解析 CSV 期间更改编码的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 上导入 CSV 期间的未知属性“headers ...”

Mechanize Rails - Web Scraping - 服务器使用JSON进行响应 - 如何将URL解析为下载CSV

如何使用pyspark在jupyter笔记本中显示我的csv数据文件

如何防止excel保存后更改csv文件编码? [复制]

ruby 更改Rails 3.2.13和4.0如何在JSONMonkey修补程序ActiveSupport中编码unicode以恢复to_json unicode字符编码。

如何在解析期间设置 github 令牌的自动更改?