Ruby 中的每个字符串都有一个底层编码。根据您LANG
和LC_ALL
环境变量,交互式 shell 可能会以给定的编码执行和解释您的字符串。
$ irb
1.9.3p392 :008 > __ENCODING__
=> #<Encoding:UTF-8>
(忽略我使用的是 Ruby 1.9 而不是 2.0,想法还是一样的)。
__ENCODING__
返回当前的源编码。你的可能也会说 UTF-8。
当您\xAE
在代码中创建文字字符串并使用字节转义符 (the) 时,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 编码提供已注册的标记字符(使用真实字符或提供两个 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®\"}"
希望能帮助到你。