2011-08-10 15 views
7

Tengo un texto que contiene secuencias de escape Unicode como \ u003C. Esto es lo que me ocurrió a unescape que:¿Es esta la mejor forma de deshacer las secuencias de escape unicode en Ruby?

string.gsub(/\u(....)/) {|m| [$1].pack("H*").unpack("n*").pack("U*")}

¿Es correcto? (es decir, parece que funciona con mis pruebas, pero ¿alguien más conocedor puede encontrar un problema?)

+0

Tienes razón. Viene de ActiveSupport :: JSON de Rails y recibe la decodificación de ActiveSupport :: JSON, pero no está decodificando el \ u escapes correctamente. (en Rails 2.1.2) –

Respuesta

17

Su expresión regular, /\u(....)/, tiene algunos problemas.

En primer lugar, \u no funciona de la forma que considera que hace, de 1,9 obtendrá un error y en 1.8 se acaba de coincidir con una sola u en lugar del par \u que está buscando; debe usar /\\u/ para encontrar el literal \u que desee.

En segundo lugar, su grupo (....) es demasiado permisivo, eso permitirá el paso de cuatro caracteres y eso no es lo que desea. En 1.9, quiere (\h{4}) (cuatro dígitos hexadecimales) pero en 1.8 necesita ([\da-fA-F]{4}) como \h es algo nuevo.

Así que si quiere que su expresión regular funcione tanto en 1.8 como 1.9, debería usar /\\u([\da-fA-F]{4})/. Esto le da lo siguiente en 1.8 y 1.9:

>> s = 'Where is \u03bc pancakes \u03BD house? And u1123!' 
=> "Where is \\u03bc pancakes \\u03BD house? And u1123!" 
>> s.gsub(/\\u([\da-fA-F]{4})/) {|m| [$1].pack("H*").unpack("n*").pack("U*")} 
=> "Where is μ pancakes ν house? And u1123!" 

Usando pack y unpack a destrozar el número hexadecimal en un carácter Unicode es probablemente lo suficientemente bueno, pero puede haber mejores maneras.

+1

También puede ser útil agregar esto como una extensión a la clase String (utilicé String # utf8_decode). – Mikey

Cuestiones relacionadas