我在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
我该如何解决这个问题?
答案 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)具有启发式,可以自动检测编码,如果您正在混合使用编码