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



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

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

"first_name"=>"ezgi xE7enberci"
"last_name" => "xFCxFExE7xF0ixFExFExF6xE7"

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

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

我该怎么解决这个问题?

怎么了

Ruby认为您有无效的字节序列,因为您的字符串不是UTF-8。例如,使用rchardet宝石:

require 'chardet'
["ezgi xE7enberci", "xFCxFExE7xF0ixFExFExF6xE7"].map do str
  puts CharDet.detect str
end

#=>[{"encoding"=>"ISO-8859-2","confidence"=>0.8600826867857209},{"encoding"=>"windows-1255","confidence"=>0.5807177322740268}]

如何修复

您需要使用String#scrub或像String#encode这样的编码方法之一!先清理一下你的绳子。例如:

hash = {"first_name"=>"ezgi xE7enberci",
        "last_name"=>"xFCxFExE7xF0ixFExFExF6xE7"}
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或其他完全不同的编码),但确保数据集的编码一致对您来说至关重要。

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

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

some_string.force_encoding("windows-1254")

然后可以使用encode方法转换为UTF8。有一些宝石(例如charlock_holmes)具有自动检测编码的启发式方法,如果您得到的是

编码的混合

最新更新