2012-10-18 9 views
32

W mojej aplikacji rails pracuję z kanałami RSS z całego świata, a niektóre kanały mają łącza, które nie są w UTF-8. Oryginalne linki do plików są poza moją kontrolą, a aby móc z nich korzystać w innych częściach aplikacji, muszą znajdować się w UTF-8.Łańcuchy sił do UTF-8 z dowolnego kodowania

Jak wykryć kodowanie i przekonwertować na UTF-8?

+0

wykryć kodowanie, trzeba analizować towarzyszący meta informacje o dokumentach, czyli nagłówki HTTP lub '' tagi. – deceze

Odpowiedz

48

Ruby 1.9

„wymuszanie” kodowanie jest łatwe, jednak nie będzie konwertować znaki wystarczy zmienić kodowanie:

str = str.force_encoding("UTF-8") 

str.encoding.name # => 'UTF-8' 

Jeśli chcesz wykonać konwersję, użyj encode:

begin 
    str.encode("UTF-8") 
rescue Encoding::UndefinedConversionError 
    # ... 
end 

pewno przeczytać poniższy wpis, aby uzyskać więcej informacji:
http://graysoftinc.com/character-encodings/ruby-19s-string

+0

dzięki za odpowiedź, artykuł też był dobry. –

+0

Nie działa: whois = whois.force_encoding ("UTF-8") \ n whois.encoding.name => "UTF-8" \ n whois.scan (/ rola: \ s + (. +)/i) - Zgłasza: ArgumentError: niepoprawna sekwencja bajtów w UTF-8 – Hackeron

+0

Jak stwierdzono, force_encoding nie konwertuje znaków iz pewnością nie potrafi w magiczny sposób interpretować niepoprawnych sekwencji bajtów UTF-8. – kwarrick

4

Iconv

require 'iconv' 
i = Iconv.new('UTF-8','LATIN1') 
a_with_hat = i.iconv("\xc2") 

Podsumowanie: gem iconv wykonuje całą pracę konwersji kodowania. Upewnić się, że zainstalowane:

gem install iconv 

Teraz trzeba wiedzieć, jakiego kodowania swój ciąg jest obecnie jako Ruby 1.8 traktuje Struny jako tablica bajtów (. Bez wewnętrznej kodowanie) Załóżmy, że ciąg był w latin1 i chcesz przekonwertować go na UTF-8

require 'iconv' 

string_in_utf8_encoding = Iconv.conv("UTF8", "LATIN1", string_in_latin1_encoding) 
+0

Dzięki za odpowiedź, ale w moim przypadku dane źródłowe są niespójne i tak naprawdę nie mam niezawodnego sposobu zapobiegania kodowaniom –

+4

Iconv nie powinien być już używany. (przestarzałe) http://stackoverflow.com/questions/8148762/iconv-deprecation-warning-with-ruby-1-9-3 – basgys

21

Zapewni to masz prawidłowe kodowanie i nie spowoduje błędu, ponieważ zastępuje dowolny niepoprawny lub niezdefiniowany znak pustym łańcuchem.

Zapewni to nie wiem co, że masz ważny UTF-8 znaków

str.encode(Encoding.find('UTF-8'), {invalid: :replace, undef: :replace, replace: ''}) 
Powiązane problemy