У меня есть строка, которую я прочитал из какого-то ввода.ruby 1.9, force_encoding, но проверьте
Насколько мне известно, это UTF8. Хорошо:
string.force_encoding("utf8")
Но если эта строка имеет байт в нем, которые не являются на самом деле правовой UTF8, я хочу знать сейчас и принять меры.
Как правило, будет принудительно повышаться («utf8»), если он встречает такие байты? I считаю это не будет.
Если бы я делал #encode, я мог бы выбрать из удобных опций, что делать с символами, которые недействительны в исходной кодировке (или кодировке назначения).
Но я не делаю #encode, я делаю #force_encoding. У этого нет таких вариантов.
ли смысл в
string.force_encoding("utf8").encode("utf8")
получить исключение сразу? Обычно кодирование от utf8 до utf8 не имеет никакого смысла. Но может быть, это способ заставить его сразу поднять, если есть недопустимые байты? Или используйте опцию :replace
и т. Д., Чтобы сделать что-то другое с недопустимыми байтами?
Но нет, похоже, не может сделать эту работу.
Кто-нибудь знает?
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
Хорошо, но как найти и устранить эти плохие байты? Как ни странно, это НЕ поднимает:
1.9.3-p0 :035 > a.encode("utf-8")
=> "bad: \xC3(okay"
Если бы я конвертировался в другую кодировку, это было бы!
1.9.3-p0 :039 > a.encode("ISO-8859-1")
Encoding::InvalidByteSequenceError: "\xC3" followed by "(" on UTF-8
Или, если бы я сказал, он заменил бы его на «?» =>
1.9.3-p0 :040 > a.encode("ISO-8859-1", :invalid => :replace)
=> "bad: ?(okay"
Так рубин получил ум, чтобы знать, что плохие байт в кодировке UTF-8, и заменить им, с чем-то еще - при преобразовании в другой кодировке. Но я не хочу хочу, чтобы преобразовать в другую кодировку, я хочу остаться utf8 - но я могу поднять, если там есть недопустимый байт, или я могу заменить недействительные байты на заменяющие символы.
Нет ли способа получить рубин для этого?
обновление Я считаю, что это, наконец, было добавлено к рубину в 2.1, с стиранием String #, представленным в предварительном выпуске 2.1, для этого. Так что ищите!
Используя Ruby 1.9.3-p484, этот ошибочно помеченный байтом \ xc0 в файле iso-8859-1 как ненадлежащее кодирование. Я обнаружил, что для моих нескольких тестовых случаев 'encode ('binary',: undef =>: replace)' похоже работает: iso-8859-1 проходит, но файл UTF-8 с неправильной последовательностью пойманы. –
См. [Этот новый ответ] (http://stackoverflow.com/a/21686992/238886) для кода, который не страдает от проблемы, о которой я упоминал выше. –