我使用的是ruby 1.9.2

我正在try 将包含一些法语单词(例如spécifié)的内容放入MySQL数据库.

当我读取CSV文件中的行时,

file_contents = CSV.read("csvfile.csv", col_sep: "$")

元素以ASCII-8BIT编码的字符串的形式返回(spécifié变成sp\xE9cifi\xE9),然后像"spécifié"这样的字符串就不能正确地保存到我的MySQL数据库中.

意思是"CSV-Yehuda Katz"表示二进制编码对ASCII数据的正确性.

所以,如果我试图让CSV强制编码如下:

file_contents = CSV.read("csvfile.csv", col_sep: "$", encoding: "UTF-8")

我得到以下错误

ArgumentError: invalid byte sequence in UTF-8: 

如果我回到原始的ASCII-8BIT编码字符串,判断CSV读取为ASCII-8BIT的字符串,它看起来像是"Non-sp\xE9cifi\xE9",而不是"Non-spécifi".

我无法通过这样做将"非sp\xE9cifi\xE9"转换为"非spécifi"

因为我得到了这个错误:

Encoding::UndefinedConversionError: "\xE9" from ASCII-8BIT to UTF-8,

Katz指出会发生这种情况,因为ASCII-8BIT并不是真正正确的字符串"编码".

Questions:

  1. Can I get CSV to read my file in the appropriate encoding? If so, how?
  2. How do I convert an ASCII-8BIT string to UTF-8 for proper storage in MySQL?

推荐答案

deceze是正确的,即ISO8859-1(又名拉丁语-1)编码文本.试试这个:

file_contents = CSV.read("csvfile.csv", col_sep: "$", encoding: "ISO8859-1")

如果这不起作用,可以使用Iconv来修复单个字符串,如下所示:

require 'iconv'
utf8_string = Iconv.iconv('utf-8', 'iso8859-1', latin1_string).first

如果latin1_string"Non sp\xE9cifi\xE9",那么utf8_string就是"Non spécifié".此外,Iconv.iconv可以一次解开整个数组:

utf8_strings = Iconv.iconv('utf-8', 'iso8859-1', *latin1_strings)

有了新的Ruby ,你可以做如下事情:

utf8_string = latin1_string.force_encoding('iso-8859-1').encode('utf-8')

其中latin1_string认为它是ASCII-8BIT,但实际上是ISO-8859-1.

Ruby相关问答推荐

Ruby 中的 Float#floor 和 Float#to_i 有什么区别?

获取用于传递参数的变量名称

从整数中 Select 重复数字的字符串

Ruby:一个方法可以返回不同类型的对象吗?

每秒做某事 x 次

是否有类似于 Ruby 的 Sinatra 的 .NET 框架?

Jekyll 默认安装没有 _layouts 目录

从 ruby​​ 脚本运行另一个 ruby​​ 脚本

RSpec 模拟对象示例

为什么 RuboCop 建议用 Array.new 替换 .times.map?

hash['key'] 到 Ruby 中的 hash.key

如何将 STDOUT 捕获到字符串?

include_examples和it_behaves_like有什么区别?

在命名包含多个单词的Ruby 时,是否应该使用破折号或下划线?

如何在不使用循环的情况下按数组中的计数分组

Ruby 中的超级关键字

Capybara:按值而不是文本 Select 选项

遍历数组的前 n 个元素

Integer 和 Fixnum 有什么区别?

如何在 Ruby 中将时间四舍五入到最接近的 15 分钟?