【问题标题】:Unescaping characters in a string with Ruby使用 Ruby 对字符串中的字符进行转义
【发布时间】:2011-05-09 10:38:53
【问题描述】:

给定以下格式的字符串(Posterous API 以这种格式返回帖子):

s="\\u003Cp\\u003E"

如何将其转换为实际的 ascii 字符,例如 s="<p>"

在 OSX 上,我成功使用了 Iconv.iconv('ascii', 'java', s),但一旦部署到 Heroku,我收到了 Iconv::IllegalSequence 异常。我猜 Heroku 部署到的系统不支持java 编码器。


我正在使用HTTParty 向Posterous API 发出请求。如果我使用 curl 发出相同的请求,那么我会 not 得到双斜杠。

来自 HTTParty github 页面:

自动将 JSON 和 XML 解析成 基于响应的红宝石哈希 内容类型

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

将明显的信息(用户名、密码、site_id、api_token)替换为有效值。

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

在这两种情况下,\u003C 等 unicode 序列都已更改为 \\u003C

【问题讨论】:

  • 您在系统上使用的 ruby​​ 版本是否与在 heroku 上使用的版本相同?
  • 看起来他们都在运行 1.8.7。
  • HTTParty 有一个format 命令,可让您指定返回和解析的格式。你有那一套吗?
  • 另外,如果您添加一些示例代码来展示您如何拨打电话,这会有所帮助。
  • @Greg 感谢您提供有关 HTTParty#format 的提示。我一直在寻找类似的东西。不幸的是,添加format :json 根本不会影响结果。

标签: ruby json escaping httparty posterous


【解决方案1】:

我找到了解决这个问题的方法。我遇到了this gist。 elskwid 遇到了同样的问题,并通过 JSON 解析器运行了字符串:

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

现在,s = "<p>"

【讨论】:

  • 我已经编辑了原始问题以澄清我是如何提出请求的,因为这似乎是双斜杠的原因。关于为什么会发生这种情况,我希望得到更好的答案。
【解决方案2】:

前几天我遇到了这个确切的问题。 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 一年半后,我才注意到您的回答。感谢您的信息!
【解决方案3】:

你也可以使用pack:

"a\\u00e4\\u3042".gsub(/\\u(....)/){[$1.hex].pack("U")} # "aäあ"

或者反过来:

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

【讨论】:

  • 哇,这是武士红宝石
【解决方案4】:

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

字符串"\u003Cp\u003E" 确实是"&lt;p&gt;",只有\u003C&lt; 的unicode,\003E&gt;

>> "\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 得到了与上述相同的行为。问题变成了,双斜线从何而来?我会继续调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
相关资源
最近更新 更多