ruby 1.9, force_encoding, но проверьте

У меня есть строка, которую я прочитал из какого-то ввода.

Насколько мне известно, это UTF8. Хорошо:

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

Но если в этой строке есть байты, которые на самом деле не являются допустимыми UTF8, я хочу знать сейчас и принять меры.

Обычно, вызывается force_encoding (& quot; utf8 & quot;), если он встречает такие байты? яbelieve Я не буду.

Если бы я делал#encode Я мог бы выбрать из удобных вариантов, что делать с символами, которые недопустимы в исходной кодировке (или кодировке назначения).

Но я не делаю #encode, я делаю #force_encoding. У него нет таких вариантов.

Будет ли смысл

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

получить исключение сразу? Обычно кодированиеfrom utf8to utf8 не имеет никакого смысла. Но, может быть, это способ получить его сразу же, если есть недействительные байты? Или используйте:replace вариант и т.д., чтобы сделать что-то другое с недопустимыми байтами?

Но нет, похоже, это тоже не сработает.

Кто-нибудь знает?

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

Хорошо, но как мне найти и устранить эти плохие байты? Как ни странно, это НЕ вызывает:

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

Если бы я конвертировал в другую кодировку, это было бы!

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

Или, если бы я сказал это, он заменил бы его на "?" = & GT;

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

Таким образом, у ruby есть все шансы узнать, что такое плохие байты в utf-8, и заменить их чем-то другим - при преобразовании в другую кодировку. Но я неwant чтобы преобразовать в другую кодировку, я хочу остаться utf8 - но я мог бы поднять, если там есть недопустимый байт, или я мог бы хотеть заменить недопустимые байты заменой символов.

Есть ли какой-нибудь способ получить рубин, чтобы сделать это?

update Я полагаю, что это наконец-то было добавлено в ruby в версии 2.1, и String # scrub присутствует в предварительной версии 2.1 для этого. Ищите это!

Ответы на вопрос(9)

Ваш ответ на вопрос