如何在 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_file
invalid byte sequence in UTF-8
尝试运行它:Iconv.conv('utf-8//IGNORE','utf-8',output)
不幸的是,我得到了那个错误:Encoding::CompatibilityError in FileImportingController#load_file
incompatible 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数据文件
ruby 更改Rails 3.2.13和4.0如何在JSONMonkey修补程序ActiveSupport中编码unicode以恢复to_json unicode字符编码。