Mỗi chuỗi trong Ruby có một mã hóa lớp phủ. Tùy thuộc vào các biến môi trường LANG
và LC_ALL
môi trường của bạn, trình bao tương tác có thể đang thực thi và diễn giải chuỗi của bạn trong một mã hóa nhất định.
$ irb
1.9.3p392 :008 > __ENCODING__
=> #<Encoding:UTF-8>
(bỏ qua tôi đang sử dụng Ruby 1.9 thay vì 2.0, ý tưởng vẫn giữ nguyên).
__ENCODING__
trả về mã hóa nguồn hiện tại. Bạn cũng có thể nói UTF-8.
Khi bạn tạo các chuỗi chữ và thoát sử dụng byte (các \xAE
) trong mã của bạn, Ruby đang cố gắng giải thích rằng theo mã hóa chuỗi:
1.9.3p392 :003 > a = {"description" => "iPhone\xAE"}
=> {"description"=>"iPhone\xAE"}
1.9.3p392 :004 > a["description"].encoding
=> #<Encoding:UTF-8>
Vì vậy, các byte \xAE
ở phần cuối của bạn chuỗi chữ sẽ được cố gắng xử lý như một byte dòng UTF-8, nhưng nó không hợp lệ. Hãy xem những gì sẽ xảy ra khi tôi cố gắng in nó:
1.9.3-p392 :001 > puts "iPhone\xAE"
iPhone�
=> nil
Bạn có thể cần phải cung cấp cho nhân vật đánh dấu đăng ký tại một mã hóa hợp lệ UTF-8 (hoặc sử dụng các nhân vật thực sự, hoặc cung cấp hai UTF-8 byte):
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®\"}"
Hoặc, nếu đầu vào của bạn là tiêu chuẩn ISO-8859-1 (tiếng Latin 1) và bạn biết điều đó chắc chắn, bạn có thể nói với Ruby để giải thích chuỗi của bạn như mã hóa khác:
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®\"}"
Hy vọng nó giúp.
chỉ trong trường hợp bạn có nghĩa là 'chỉ coi nó như nó là', bạn có thể tăng gấp đôi thoát nó: {"description" => "iPhone \\ xAE"}. To_json => "{\" description \ ": \ "iPhone \\\ \ xAE \"} " –