使用Ruby对字符串中的字符进行反转义

3

给定一个字符串的格式(Posterous API以此格式返回帖子):

s="\\u003Cp\\u003E"

如何将字符串 s="<p>" 转换成实际的 ASCII 字符?
在 OSX 上,我成功地使用了 Iconv.iconv('ascii', 'java', s),但是一旦部署到 Heroku 上,就会收到 Iconv::IllegalSequence 异常。我猜测 Heroku 所部署的系统不支持 java 编码器。
我正在使用 HTTParty 发起对 Posterous API 的请求。如果我使用 curl 进行同样的请求,则不会出现双斜杠。
从 HTTParty 的 github 页面可以看到:

根据响应 content-type 自动将 JSON 和 XML 解析为 Ruby 哈希

而 Posterous API 返回的是 JSON(没有双斜杠),但 HTTParty 的 JSON 解析却插入了双斜杠。
以下是我使用 HTTParty 进行请求的简单示例。
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

请将明显的信息(用户名,密码,站点ID,API令牌)替换为有效值。

在切入点处,response.body包含一个以JSON格式呈现的Ruby字符串,而response.parsed_response包含一个Ruby哈希对象,HTTParty通过解析来自Posterous API的JSON响应创建了它。

在这两种情况下,像\u003C这样的Unicode序列已更改为\\u003C


你的系统上使用的 Ruby 版本和 Heroku 上使用的版本一样吗? - mpapis
看起来它们都在运行1.8.7版本。 - hiwaylon
HTTParty有一个format命令,可以让你指定返回和解析的格式。你设置了吗? - the Tin Man
此外,如果您添加一些示例代码显示您如何进行调用,那将会很有帮助。 - the Tin Man
@Greg 谢谢你提供关于HTTParty#format的技巧。我一直在寻找类似的东西。不幸的是,添加“format:json”并没有影响结果。 - hiwaylon
4个回答

3

我找到了解决这个问题的方法。我偶然发现了这个代码片段。elskwid遇到了同样的问题,并将字符串通过JSON解析器运行:

s = ::JSON.parse("\\u003Cp\\u003E")

现在,s = "<p>"

我已编辑原始问题以澄清我的请求方式,因为这似乎是双斜杠的原因。我希望能得到更好的答案,解释为什么会发生这种情况。 - hiwaylon

1
我前几天遇到了这个确切的问题。HTTParty使用的json解析器(Crack gem)存在一个错误 - 基本上它使用区分大小写的正则表达式来处理Unicode序列,因此由于Posterous输出A-F而不是a-f,Crack无法对其进行反转义。我提交了一个拉取请求来修复这个问题。
与此同时,HTTParty很好地让你指定替代解析器,所以你可以像这样绕过Crack完全使用::JSON.parse
class JsonParser < HTTParty::Parser
  def json
    ::JSON.parse(body)
  end
end

class Posterous
   include HTTParty
   parser ::JsonParser

   #....
end

+1 我刚刚注意到你的回答,一年半后。感谢提供信息! - hiwaylon

1
您也可以使用pack
"a\\u00e4\\u3042".gsub(/\\u(....)/){[$1.hex].pack("U")} # "aäあ"

或者反过来做:
"aäあ".gsub(/[^ -~\n]/){"\\u%04x"%$&.ord} # "a\\u00e4\\u3042"

哇,这就是侍Ruby。 - urmurmur

0

双反斜杠看起来几乎像是在调试器中查看的常规字符串。

字符串"\u003Cp\u003E"实际上是"<p>",只有\u003C<的Unicode表示,\u003E>的Unicode表示。

>> "\u003Cp\u003E"  #=> "<p>"

如果您确实获得了带有双反斜杠的字符串,则可以尝试去掉其中一对。

作为测试,请查看字符串的长度:

>> "\\u003Cp\\u003E".size #=> 13
>> "\u003Cp\u003E".size #=> 3
>> "<p>".size #=> 3

以上所有操作都是使用了支持Unicode的Ruby 1.9.2完成的,而v1.8.7则不支持。以下是我使用1.8.7的IRB进行比较所得到的结果:
>> "\u003Cp\u003E" #=> "u003Cpu003E"

我使用两个不同版本的Ruby得到了与上述相同的行为。问题是,这些双斜杠是从哪里来的?我将继续调查。 - hiwaylon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接