Ruby 2.1.5 - ArgumentError: invalid byte sequence in UTF-8
Ruby 2.1.5 - ArgumentError: invalid byte sequence in 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
我该如何解决这个问题?
这看起来不像是 utf-8 数据,所以这个异常是正常的。听起来你需要告诉 ruby 字符串实际上是什么编码:
some_string.force_encoding("windows-1254")
然后您可以使用 encode
方法转换为 UTF8。有一些 gems(例如 charlock_holmes)可以启发式地自动检测编码,如果你得到的是混合编码
怎么了
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", "confidence"=>0.8600826867857209},
{"encoding"=>"windows-1255", "confidence"=>0.5807177322740268}]
如何修复
您需要先使用 String#scrub or one of the encoding methods like 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 或其他完全不同的编码),但要确保您拥有一致的编码数据集的编码对您来说至关重要。
字符编码检测不完善。最好的办法是尝试找出外部数据源使用的编码,并在字符串编码中使用它,而不是尝试自动检测它。否则,您的里程可能会有所不同。
我在 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
我该如何解决这个问题?
这看起来不像是 utf-8 数据,所以这个异常是正常的。听起来你需要告诉 ruby 字符串实际上是什么编码:
some_string.force_encoding("windows-1254")
然后您可以使用 encode
方法转换为 UTF8。有一些 gems(例如 charlock_holmes)可以启发式地自动检测编码,如果你得到的是混合编码
怎么了
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", "confidence"=>0.8600826867857209}, {"encoding"=>"windows-1255", "confidence"=>0.5807177322740268}]
如何修复
您需要先使用 String#scrub or one of the encoding methods like 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 或其他完全不同的编码),但要确保您拥有一致的编码数据集的编码对您来说至关重要。
字符编码检测不完善。最好的办法是尝试找出外部数据源使用的编码,并在字符串编码中使用它,而不是尝试自动检测它。否则,您的里程可能会有所不同。