2012-01-03 11 views
25

Supongamos que tiene una cadena como "€foo\xA0", codificada UTF-8. ¿Hay alguna forma de eliminar las secuencias de bytes no válidas de esta cadena? (para que obtenga "€foo")¿Hay alguna manera en ruby ​​1.9 de eliminar secuencias inválidas de bytes de cadenas?

En ruby-1.8 puede usar Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "€foo\xA0") pero eso ya no está disponible. "€foo\xA0".encode('UTF-8') no hace nada, ya que ya es UTF-8. Probé:

"€foo\xA0".force_encoding('BINARY').encode('UTF-8', :undef => :replace, :replace => '') 

que produce

"foo"

Pero eso también pierde el carácter de varios bytes válidos €

Respuesta

32
"€foo\xA0".chars.select(&:valid_encoding?).join 
+1

No elimina el '\ xF1' en esta cadena' "eEspa \ xF1a; FB" ' – Dorian

+1

@Dorian, en la consola 1.9.3 IRB,' "eEspa \ xF1a; FB" .chars.select {| i | i.valid_encoding?}. join' returns '" eEspaa; FB "' ... ¿no tienes ese comportamiento o he malentendido? – acobster

34
"€foo\xA0".encode('UTF-16le', invalid: :replace, replace: '').encode('UTF-8') 
+0

¿Puedo preguntar por qué "UTF-16le"? – lulalala

+2

Tenía la impresión de que tiene un juego de caracteres más grande que UTF-8, lo que significa que no pierde ningún dato válido. Lamentablemente, lo siguiente no funciona: '" € foo \ xA0 ".encode ('UTF-8',: invalid =>: replace,: replace => '')' porque la cadena ya es UTF- 8, por lo que no se codificará de nuevo. –

+0

FWIW, ejecutando una prueba en un archivo grande Encontré este método en un orden de magnitud más rápido que el enfoque 'valid_encoding'. – jwadsack

-2
data = '' if not (data.force_encoding("UTF-8").valid_encoding?) 
+0

Esto no proporciona una respuesta a la pregunta. Para criticar o solicitar aclaraciones de un autor, deje un comentario debajo de su publicación; siempre puede comentar sus propias publicaciones, y una vez que tenga suficiente [reputación] (http://stackoverflow.com/help/whats-reputation) lo hará poder [comentar cualquier publicación] (http://stackoverflow.com/help/privileges/comment). – Severin

+0

@Severin ¿por qué no? Parece una respuesta (incorrecta) a la pregunta. Elimina todas las secuencias de bytes inválidos de una cadena. Simplemente elimina todos los válidos también. –

1

de Ruby 2.0 y 1.9.3

"€foo\xA0".encode(Encoding::UTF_8, Encoding::UTF_8, :invalid => :replace) 

Rubí 2.1+

"€foo\xA0".scrub 
Cuestiones relacionadas