caractères déséchapper dans une chaîne avec Ruby
Question
d'une chaîne dans le format suivant (les API retourne Posterous messages dans ce format):
s="\\u003Cp\\u003E"
Comment puis-je convertir les caractères ascii réels tels que s="<p>"
?
Sur Mac OS X, j'utilisé avec succès Iconv.iconv('ascii', 'java', s)
mais une fois déployé à Heroku, je reçois une exception Iconv::IllegalSequence
. Je devine que le système Heroku déploie pour does't soutenir l'encodeur java
.
J'utilise HTTParty pour faire une demande à l'API Posterous. Si j'utilise une boucle pour faire la même demande alors je fais pas obtenir les doubles barres obliques.
De la page HTTParty github:
automatique de l'analyse syntaxique JSON et XML en hachages rubis basé sur la réponse -Type de contenu
L'API retourne Posterous JSON (pas de double barre oblique) et l'analyse syntaxique de JSON HTTParty est la double barre oblique insérait.
Voici un exemple simple de la façon dont je me sers HTTParty pour faire la demande.
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
Avec les informations évidentes (nom d'utilisateur, mot de passe, site_id, api_token) remplacées par des valeurs valides.
Au point de snip, response.body
contient une chaîne Ruby qui est au format JSON et response.parsed_response
contient un objet de hachage Ruby qui HTTParty créée par analyse de la réponse de l'API JSON Posterous.
Dans les deux cas, les séquences unicode telles que \u003C
ont été modifiés pour \\u003C
.
La solution
je suis tombé sur ce problème exactement l'autre jour. Il y a un bogue dans l'analyseur de JSON HTTParty utilise (gemme Crack) - fondamentalement, il utilise une expression rationnelle sensible à la casse pour les séquences Unicode, parce que Posterous met sur A-F au lieu d'un f, Crack ne sont pas les déséchapper. Je présenté une demande de traction pour résoudre ce problème.
En attendant HTTParty vous permet de spécifier bien parseurs alternatives afin que vous puissiez faire ::JSON.parse
sans qu'intervienne Crack comme ceci:
class JsonParser < HTTParty::Parser
def json
::JSON.parse(body)
end
end
class Posterous
include HTTParty
parser ::JsonParser
#....
end
Autres conseils
Je l'ai trouvé une solution à ce problème. Je couru à travers ce point essentiel . elskwid a eu le même problème et a couru la chaîne par un analyseur de JSON:
s = ::JSON.parse("\\u003Cp\\u003E")
Maintenant, s = "<p>"
.
Vous pouvez également utiliser pack
:
"a\\u00e4\\u3042".gsub(/\\u(....)/){[$1.hex].pack("U")} # "aäあ"
Ou faire l'inverse:
"aäあ".gsub(/[^ -~\n]/){"\\u%04x"%$&.ord} # "a\\u00e4\\u3042"
Les slashes doublé ressemblent presque à une chaîne régulière étant affiché dans un débogueur.
La "\u003Cp\u003E"
chaîne est vraiment "<p>"
, seule la \u003C
est unicode pour <
et \003E
est >
.
>> "\u003Cp\u003E" #=> "<p>"
Si vous obtenez réellement la chaîne avec antislashs alors vous pourriez doublé essayer de décapage de la paire.
Comme un test, voir combien de temps la chaîne est:
>> "\\u003Cp\\u003E".size #=> 13
>> "\u003Cp\u003E".size #=> 3
>> "<p>".size #=> 3
Tout ce qui précède a été fait en utilisant Ruby 1.9.2, qui est au courant Unicode. v1.8.7 n'a pas été. Voici ce que je reçois l'aide de la CISR 1.8.7 pour la comparaison:
>> "\u003Cp\u003E" #=> "u003Cpu003E"