Ruby 2.1.5 - ArgumentError:UTF-8中的无效字节序列

时间:2015-02-12 12:14:20

标签: ruby-on-rails ruby ruby-on-rails-4 utf-8

我在Ruby 2.1.5和Rails 4中遇到UTF8字符问题。

问题是,来自外部服务的数据是这样的:

"first_name"=>"ezgi \xE7enberci"
"last_name" => "\xFC\xFE\xE7\xF0i\xFE\xFE\xF6\xE7"

这些字符大多包括土耳其字母字符,如“üğşiçö”。当应用程序尝试保存这些数据时,会出现以下错误:

ArgumentError: invalid byte sequence in UTF-8
Mysql2::Error: Incorrect string value

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

什么是错的

Ruby认为你的字节序列无效,因为你的字符串不是UTF-8。例如,使用rchardet gem

require 'chardet'
["ezgi \xE7enberci", "\xFC\xFE\xE7\xF0i\xFE\xFE\xF6\xE7"].map do str
  puts CharDet.detect str
end
  

#=> [{“encoding”=>“ISO-8859-2”,“置信度”=> 0.8600826867857209},        {“encoding”=>“windows-1255”,“置信度”=> 0.5807177322740268}]

如何修复

您需要先使用String#scrub或其中一种编码方法(如String#encode!)来清理字符串。例如:

hash = {"first_name"=>"ezgi \xE7enberci",
        "last_name"=>"\xFC\xFE\xE7\xF0i\xFE\xFE\xF6\xE7"}
hash.each_pair { |k,v| k[v.encode! "UTF-8", "ISO-8859-2"] }
#=> {"first_name"=>"ezgi çenberci", "last_name"=>"üţçđiţţöç"}

显然,您可能需要进行一些实验来弄清楚正确的编码是什么(例如ISO-8859-2,windows-1255或其他完全不同的东西),但要确保您的数据集具有一致的编码,对你来说至关重要。

字符编码检测不完善。您最好的选择是尝试找出外部数据源使用的编码,并在字符串编码中使用它,而不是尝试自动检测它。否则,您的里程可能会有所不同。

答案 1 :(得分:1)

这看起来不像utf-8数据所以这个例外是正常的。听起来你需要告诉ruby字符串实际上是什么编码:

some_string.force_encoding("windows-1254")

然后,您可以使用encode方法转换为UTF8。有宝石(例如charlock_holmes)具有启发式,可以自动检测编码,如果您正在混合使用编码