La representación no literal caracteres de una cadena con Ruby
Pregunta
Dada una cadena con el siguiente formato (las API devuelve Posterous mensajes en este formato):
s="\\u003Cp\\u003E"
¿Cómo puedo convertir a los caracteres ASCII reales tal que s="<p>"
?
Iconv.iconv('ascii', 'java', s)
en OSX, he utilizado con éxito, pero una vez desplegado a Heroku, que reciben una excepción Iconv::IllegalSequence
. Supongo que el sistema despliega a Heroku does't apoyar el codificador java
.
Estoy utilizando HTTParty para hacer una petición a la API de Posterous. Si uso rizo para hacer la misma petición que hago a continuación, no obtener las dobles barras.
De HTTParty github página:
automático de análisis de JSON y XML en hashes rubí basados ??en la respuesta De tipo de contenido
El API Posterous devuelve JSON (sin barras dobles) y HTTParty de análisis sintáctico JSON es la inserción de la doble barra.
Aquí es un simple ejemplo de la forma en que estoy usando HTTParty para realizar la solicitud.
class Posterous
include HTTParty
base_uri "http://www.posterous.com/api/2"
basic_auth "username", "password"
format :json
def get_posts
response = Posterous.get("/users/me/sites/9876/posts&api_token=1234")
# snip, see below...
end
end
Con la información obvia (nombre de usuario, contraseña, site_id, api_token) sustituido con valores válidos.
En el punto de recorte, response.body
contiene una cadena de Ruby que está en formato JSON y response.parsed_response
contiene un objeto hash Rubí, que HTTParty creado por analizar la respuesta JSON de la API de Posterous.
En ambos casos las secuencias Unicode como \u003C
han sido cambiados para \\u003C
.
Solución
me encontré con este problema exacto, el otro día. Hay un error en el analizador JSON que utiliza HTTParty (crack de la gema) - básicamente se utiliza una expresión regular entre mayúsculas y minúsculas para las secuencias de Unicode, por lo que debido a Posterous apaga A-F en lugar de a-f, grieta no se unescape ellos. Presenté una solicitud de extracción de solucionar este problema.
Mientras tanto HTTParty bien le permite especificar analizadores alternativos para que pueda hacer ::JSON.parse
sin pasar por la grieta en su totalidad como esto:
class JsonParser < HTTParty::Parser
def json
::JSON.parse(body)
end
end
class Posterous
include HTTParty
parser ::JsonParser
#....
end
Otros consejos
he encontrado una solución a este problema. Me encontré con este GIST . elskwid tenía el mismo problema y se pasó la cadena a través de un analizador JSON:
s = ::JSON.parse("\\u003Cp\\u003E")
Ahora, s = "<p>"
.
También puede utilizar pack
:
"a\\u00e4\\u3042".gsub(/\\u(....)/){[$1.hex].pack("U")} # "aäあ"
O para hacer a la inversa:
"aäあ".gsub(/[^ -~\n]/){"\\u%04x"%$&.ord} # "a\\u00e4\\u3042"
Las barras invertidas-duplicado casi se parece a una cadena normal que se está viendo en un depurador.
La cadena "\u003Cp\u003E"
realmente es "<p>"
, sólo el \u003C
es Unicode para <
y \003E
es >
.
>> "\u003Cp\u003E" #=> "<p>"
Si usted está consiguiendo verdad la cadena con barras invertidas se duplicó entonces usted podría intentar despojar a uno de la pareja.
A modo de prueba, consulte el tiempo que la cadena es:
>> "\\u003Cp\\u003E".size #=> 13
>> "\u003Cp\u003E".size #=> 3
>> "<p>".size #=> 3
Todo lo anterior se hizo utilizando Rubí 1.9.2, que es Unicode consciente. v1.8.7 no lo era. Esto es lo que consigo el uso del IRB 1.8.7 para la comparación:
>> "\u003Cp\u003E" #=> "u003Cpu003E"