ruby 1.9, force_encoding, ale sprawdź

Mam ciąg, który przeczytałem z jakiegoś wejścia.

Według mojej najlepszej wiedzy jest to UTF8. W porządku:

<code>string.force_encoding("utf8")
</code>

Ale jeśli ten ciąg zawiera bajty, które w rzeczywistości nie są legalnym UTF8, chcę teraz wiedzieć i podjąć działanie.

Zwykle, czy force_encoding ("utf8") podbije, jeśli napotka takie bajty? jauwierzyć nie będzie.

Gdybym robił#kodować Mógłbym wybrać z poręcznych opcji, co zrobić ze znakami, które są nieprawidłowe w kodowaniu źródłowym (lub kodowaniu docelowym).

Ale nie robię kodu #en, robię #force_encoding. Nie ma takich opcji.

Czy miałoby to sens

<code>string.force_encoding("utf8").encode("utf8")
</code>

od razu uzyskać wyjątek? Normalnie kodowaniez utf8do utf8 nie ma sensu. Ale może to jest sposób, aby go podnieść od razu, jeśli są nieprawidłowe bajty? Lub użyj:replace opcja itp., aby zrobić coś innego z nieprawidłowymi bajtami?

Ale nie, nie wydaje mi się, żeby to działało.

Ktoś wie?

<code>1.9.3-p0 :032 > a = "bad: \xc3\x28 okay".force_encoding("utf-8")
=> "bad: \xC3( okay"
1.9.3-p0 :033 > a.valid_encoding?
=> false
</code>

Ok, ale jak znaleźć i wyeliminować te złe bajty? Co dziwne, to NIE podnosi:

<code>1.9.3-p0 :035 > a.encode("utf-8")
 => "bad: \xC3( okay"
</code>

Gdybym przechodził na inne kodowanie, to by się udało!

<code>1.9.3-p0 :039 > a.encode("ISO-8859-1")
Encoding::InvalidByteSequenceError: "\xC3" followed by "(" on UTF-8
</code>

Albo gdybym to powiedział, zastąpiłoby to „?” =>

<code>1.9.3-p0 :040 > a.encode("ISO-8859-1", :invalid => :replace)
=> "bad: ?( okay"
</code>

Tak więc ruby ​​mają mądrości, aby wiedzieć, jakie są złe bajty w utf-8 i zastąpić je czymś innym - podczas konwersji na inne kodowanie. Ale ja niechcieć Aby przekonwertować na inne kodowanie, chcę pozostać utf8 - ale może chciałbym podnieść, jeśli jest tam niepoprawny bajt, lub mogę zastąpić nieprawidłowe bajty znakami zastępczymi.

Czy nie ma sposobu, aby to zrobić?

aktualizacja Wierzę, że w końcu został dodany do ruby ​​w wersji 2.1, z tym że String # scrub jest dostępny w wersji 2.1. Więc szukajcie tego!

questionAnswers(9)

yourAnswerToTheQuestion