У меня есть строка, которую я прочитал из какого-то ввода.
Насколько мне известно, это UTF8. Хорошо:
string.force_encoding("utf8")
Но если в этой строке есть байты, которые на самом деле не являются законными UTF8, я хочу знать сейчас и принять меры.
Как правило, будет принудительно повышаться ( "utf8" ), если он встречает такие байты? Я верю, что этого не произойдет.
Если я делал # 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"
Итак, Ruby получил умения, чтобы узнать, что такое плохие байты в utf-8, и заменить их чем-то другим - при преобразовании в другую кодировку. Но я не хочу конвертировать в другую кодировку, я хочу остаться utf8 - но я могу захотеть поднять, если там есть недопустимый байт, или я могу заменить недействительные байты на заменяющие символы.
Нет ли способа получить рубин для этого?
update. Полагаю, что это, наконец, было добавлено в ruby в версии 2.1, с чипом String #, присутствующим в версии предварительного просмотра 2.1, для этого. Так что ищите!