Ruby のすべての文字列には、基になるエンコーディングがあります。環境変数によってはLANG
、インタラクティブ シェルが特定のエンコーディングで文字列を実行および解釈している可能性があります。LC_ALL
$ irb
1.9.3p392 :008 > __ENCODING__
=> #<Encoding:UTF-8>
(Ruby 2.0 ではなく 1.9 を使用していることは無視してください。考え方は同じです)。
__ENCODING__
現在のソース エンコーディングを返します。あなたはおそらくUTF-8とも言うでしょう。
コードでリテラル文字列を作成し、バイト エスケープ ( \xAE
) を使用すると、Ruby は文字列エンコーディングに従ってそれを解釈しようとします。
1.9.3p392 :003 > a = {"description" => "iPhone\xAE"}
=> {"description"=>"iPhone\xAE"}
1.9.3p392 :004 > a["description"].encoding
=> #<Encoding:UTF-8>
そのため、リテラル文字列の最後のバイト\xAE
は UTF-8 ストリーム バイトとして扱われるように試みられますが、無効です。印刷しようとするとどうなるか見てみましょう:
1.9.3-p392 :001 > puts "iPhone\xAE"
iPhone�
=> nil
登録されたマーク文字を有効な UTF-8 エンコーディングで提供する必要があります (実際の文字を使用するか、2 つの UTF-8 バイトを提供します)。
1.9.3-p392 :002 > a = {"description1" => "iPhone®", "description2" => "iPhone\xc2\xae"}
=> {"description1"=>"iPhone®", "description2"=>"iPhone®"}
1.9.3-p392 :005 > a.to_json
=> "{\"description1\":\"iPhone®\",\"description2\":\"iPhone®\"}"
または、入力が ISO-8859-1 (Latin 1) であり、それが確実にわかっている場合は、文字列を別のエンコーディングとして解釈するよう Ruby に指示できます。
1.9.3-p392 :006 > a = {"description1" => "iPhone\xAE".force_encoding('ISO-8859-1') }
=> {"description1"=>"iPhone\xAE"}
1.9.3-p392 :007 > a.to_json
=> "{\"description1\":\"iPhone®\"}"
それが役に立てば幸い。