Każdy ciąg w Ruby ma underlaying encoding. W zależności od zmiennych środowiskowych LANG
i LC_ALL
, interaktywna powłoka może wykonywać i interpretować łańcuchy w danym kodowaniu.
$ irb
1.9.3p392 :008 > __ENCODING__
=> #<Encoding:UTF-8>
(zignorować, że używam Ruby 1.9 zamiast 2.0, pomysły są nadal takie same).
__ENCODING__
zwraca bieżące kodowanie źródła. Najprawdopodobniej Twój kod będzie również oznaczony jako UTF-8.
Podczas tworzenia dosłowne ciągi i ucieka użycie bajt (The \xAE
) w kodzie, Ruby próbuje tłumaczyć, że zgodnie z kodowaniem strun:
1.9.3p392 :003 > a = {"description" => "iPhone\xAE"}
=> {"description"=>"iPhone\xAE"}
1.9.3p392 :004 > a["description"].encoding
=> #<Encoding:UTF-8>
Więc bajt \xAE
na końcu ciąg literowy będzie próbował być traktowany jako bajt strumienia UTF-8, ale jest nieważny. Zobacz, co się dzieje, gdy próbuję go wydrukować:
1.9.3-p392 :001 > puts "iPhone\xAE"
iPhone�
=> nil
albo trzeba zapewnić zarejestrowanemu znakowi charakter w poprawnym kodowaniem UTF-8 (przy użyciu prawdziwego charakteru lub dostarczenie dwóch bajtów 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®\"}"
Lub, jeśli wejście jest ISO-8859-1 (Latin 1) i wiesz, to na pewno można powiedzieć Ruby interpretować swój ciąg jako innym kodowaniu:
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®\"}"
nadzieję, że pomaga.
na wszelki wypadek, jeśli masz na myśli "potraktuj to tak, jak jest", możesz dwukrotnie uciec przed nim: {"description" => "iPhone \\ xAE"}. To_json => "{\" description \ ": \ "iPhone \\\\ xAE \"} " –