ruby 1.9, force_encoding, pero compruebe

Tengo una cadena que he leído de algún tipo de entrada.

Que yo sepa, es UTF8. Bueno:

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

Pero si esta cadena tiene bytes que no son de hecho UTF8 legal, quiero saber ahora y actuar.

Por lo general, ¿force_encoding ("utf8") aumentará si encuentra dichos bytes? yocreer no lo hará.

Si estuviera haciendo un#codificar Podría elegir entre las opciones útiles con qué hacer con los caracteres que no son válidos en la codificación de origen (o codificación de destino).

Pero no estoy haciendo un #encode, estoy haciendo un #force_encoding. No tiene tales opciones.

¿Tendría sentido

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

para obtener una excepción de inmediato? Normalmente codificandodesde utf8a utf8 no tiene ningún sentido. ¿Pero tal vez esta es la manera de hacer que se aumente de inmediato si hay bytes no válidos? O usa el:replace ¿Opción etc para hacer algo diferente con bytes inválidos?

Pero no, parece que tampoco puede hacer que eso funcione.

¿Nadie sabe?

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

Está bien, pero ¿cómo encuentro y elimino esos bytes malos? Curiosamente, esto NO plantea:

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

Si estuviera convirtiendo a una codificación diferente, lo haría!

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

O si se lo dijera, lo reemplazaría con un "?" =>

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

Así que Ruby tiene la inteligencia de saber cuáles son los bytes defectuosos en utf-8, y de reemplazarlos con otra cosa, cuando se convierte a una codificación diferente. Pero yo noquerer para convertir a una codificación diferente, quiero permanecer utf8, pero podría aumentar si hay un byte no válido allí, o podría reemplazar bytes no válidos con caracteres de reemplazo.

¿No hay alguna manera de conseguir que Ruby haga esto?

actualizar Creo que esto finalmente se agregó a ruby ​​en 2.1, con String # scrub presente en la versión preliminar de 2.1 para hacer esto. Así que busca eso!

Respuestas a la pregunta(9)

Su respuesta a la pregunta