我在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)具有自动检测编码的启发式方法,如果您得到的是