web-dev-qa-db-ja.com

Encoding :: UndefinedConversionError

ハッシュをJSON文字列に変換しようとするたびに_Encoding::UndefinedConversionError - "\xC2" from ASCII-8BIT to UTF-8_を取得し続けます。私は[.encode | .force_encoding](["UTF-8" | "ASCII-8BIT" ])を試し、_.encode_を_.force_encoding_と連鎖させ、逆方向に、パラメーターを切り替えましたが、何も機能していないようで、次のようなエラーをキャッチしました:

_begin
  menu.to_json
rescue Encoding::UndefinedConversionError
  puts $!.error_char.dump
  p $!.error_char.encoding
end
_

Menuは、MySQL DBのコンテンツを含む続編のdataset.to_hashであり、utf8_general_ciエンコーディングであり、これを返しました。

「\ xC2」

<#Encoding:ASCII-8BIT>

使用する_.encode_/_.force_encoding_に関係なく、エンコードは変更されません。文字列.gsub!(/\\\xC2/)を運なしで置き換えようとしました。

何か案は?

34
martriay
menu.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')

これは完全に機能し、余分な文字をいくつか置き換える必要がありましたが、エラーはもうありません。

75
martriay

「\ xC2」に何を期待しますか?おそらくÂ

ASCII-8BITを使用すると、バイナリデータが得られ、Rubyが何をすべきか決定できません。

最初にforce_encodingでエンコードを設定する必要があります。

次のコードを試すことができます。

Encoding.list.each{|enc|
  begin
    print "%-10s\t" % [enc]
    print "\t\xC2".force_encoding(enc)
    print "\t\xC2".force_encoding(enc).encode('utf-8')
  rescue => err
    print "\t#{err}"
  end
  print "\n"
}

結果は、「\ xC2」のさまざまなエンコーディングで可能な値です。

結果は出力形式に依存する場合がありますが、どのエンコードを使用しているかをよく推測できると思います。

必要なエンコーディング(おそらくcp1251)を定義すると、次のことができます。

menu.force_encoding('cp1252').to_json

Kashyapsコメントも参照してください。

18
knut

奇妙なキャラクターを失うことを気にしない場合、それらを吹き飛ばすことができます:

str.force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')
11
Ponny

自動承認されたソリューションは機能せず、事実上エラーはありませんが、JSONではありません。

Oj gemを使用して問題を解決しましたが、今では見つけることができます。また、標準のJSONライブラリよりも高速です。

書く:

   menu_json = Oj.dump menu

読書:

   menu2 = Oj.load menu_json

https://github.com/ohler55/oj 詳細については。私はそれが役立つことを願っています。

8
gvo