2012-10-21 16 views
24

Otrzymuję zawsze Encoding::UndefinedConversionError - "\xC2" from ASCII-8BIT to UTF-8 za każdym razem, gdy próbuję przekonwertować skrót na ciąg JSON. Próbowałem z [.encode | .force_encoding](["UTF-8" | "ASCII-8BIT" ]), łańcuchowym .encode z .force_encoding, do tyłu, przełączanie parametrów, ale nic nie wydawało się do pracy, więc złapałem błędu takiego:Kodowanie :: UndefinedConversionError

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

Gdzie menu jest dataset.to_hash sequel za treści z MySQL DB, utf8_general_ci kodowanie i wrócił to:

"\ xC2"

< #Encoding: ASCII-8BIT>

Kodowanie nigdy się nie zmienia, niezależnie od używanego urządzenia. Próbowałem nawet zastąpić ciąg .gsub!(/\\\xC2/) bez powodzenia.

Wszelkie pomysły?

+1

1. Czy próbowałeś tego? 'menu.force_encoding (" ISO-8859-1 ") .okodować (" UTF-8 ")' 2. dodać "# encoding" utf-8'' string na górze wszystkich plików .rb. 3 Sprawdź ustawienia środowiska, co mówi '$ echo LC_CTYPE' w twoim terminalu? – Kashyap

+0

Czy krok 1 zakończył się błędem? Czy wykonano krok 2? Dla kroku 3, http://thegreyblog.blogspot.in/2012/02/ Naprawianie-mac-os-x-lions-ssh-utf-8-issues.html ten link ma ustawienia env, które twój program musi uruchamiać z incase, którego chcesz uniknąć problemu – Kashyap

Odpowiedz

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

To działało idealnie, musiałem wymienić jakieś dodatkowe znaki, ale nie ma więcej błędów.

+1

Fantastyczne rozwiązanie - rozwiązałem mój problem dotyczący dziwnych typów w SQL Server. Dziękuję Ci! –

+0

Dzięki. Lubię znajdować odpowiedzi bez nurkowania w dokumentach. –

+0

Dzięki! To działa również dla mnie, oficjalny dokument ruby ​​na przyszłość [tutaj] (http://www.ruby-doc.org/core-2.1.2/String.html#method-i-encode) – jmoreira

14

Czego oczekujesz od "\ xC2"? Prawdopodobnie z ASCII-8BIT masz dane binarne i ruby ​​nie mogą zdecydować, co powinno być.

Najpierw należy ustawić kodowanie za pomocą force_encoding.

Możesz spróbować następujący kod:

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" 
} 

Rezultatem są możliwe wartości w różnych kodowań dla Twojej „\ xC2”.

Wynik może zależeć od formatu wyjściowego, ale myślę, że możesz zgadywać, jakie kodowanie posiadasz.

Gdy zdefiniowane kodowanie trzeba (prawdopodobnie cp1251) można

menu.force_encoding('cp1252').to_json 

Zobacz również Kashyaps komentarz.

+0

Oto, co zrobiłem: 'Encoding .list.each {| enc | rozpocznij wydrukuj "% -10s \ t"% [enc] menu drukowania.to_json.force_encoding (enc) menu drukowania.to_json.force_encoding (enc) .encode ('utf-8 ") ratowanie => błądzić print "\ t # {err}" koniec print "\ n" } ' i to, co mam do każdego wyniku: 'SJIS-KDDI "\ xC2" od ASCII-8BIT do UTF-8' – martriay

7

Jeśli nie dbają o utratę dziwnych znaków, można wysadzić je z daleka:

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

Nie działa :( Kodowanie :: UndefinedConversionError w/menu "\ xC2" z ASCII-8BIT na UTF-8 – martriay

+3

menu.to_s.encode ('UTF-8', { : invalid =>: replace,: undef =>: replace,: replace => '?'}) -> działało! : D – martriay

6

Twoje automatycznie akceptowane rozwiązanie nie działa, nie występują skutecznie żadne błędy, ale jest to NOT JSON.

Rozwiązałem problem za pomocą klejnotu oj, teraz działa. Jest także szybszy niż standardowa biblioteka JSON.

pisanie:

menu_json = Oj.dump menu 

Reading:

menu2 = Oj.load menu_json 

https://github.com/ohler55/oj więcej szczegółów.Mam nadzieję, że to pomoże.

+0

Problem polegał na błędzie , a nie część JSON. Dlatego moje automatycznie akceptowane odpowiedzi działają. W każdym razie zabiorę cię za podanie alternatywnego rozwiązania. – martriay

+0

Cóż, zgadzam się z tobą, nie ma już błędów, ale to nie jest ciąg jsonów. Nie wiem, jaki był twój cel, ale musiałem załadować mój json i chciałem mieć prawidłowy ciąg JSON. A może przegapiłem coś w proponowanym przez ciebie rozwiązaniu? – gvo

+0

To pytanie dotyczyło tylko błędu, nie mówię, że moja odpowiedź jest najlepszym wyborem, oczywiście nie jest to dla twojego celu, ale rozwiązuje przedstawiony problem: błąd kodowania. Wspomniany JSON w moim pytaniu dotyczy celów kontekstualizacji. – martriay