【问题标题】:Is this the best way to unescape unicode escape sequences in Ruby?这是在 Ruby 中取消转义 unicode 转义序列的最佳方法吗?
【发布时间】:2011-08-10 18:21:32
【问题描述】:

我有一些包含 Unicode 转义序列的文本,例如 \u003C。这就是我想出的逃避它的方法:

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

正确吗? (即,它似乎适用于我的测试,但知识渊博的人能找到它的问题吗?)

【问题讨论】:

  • 没错。它来自 Rails 的 ActiveSupport::JSON 并被 ActiveSupport::JSON 解码,但它没有正确解码 \u 转义。 (在 Rails 2.1.2 上)

标签: ruby unicode


【解决方案1】:

您的正则表达式 /\u(....)/ 有一些问题。

首先,\u 不会像你想象的那样工作,在 1.9 中你会得到一个错误,在 1.8 中它只会匹配一个 u 而不是你认为的 \u 对'正在寻找;你应该使用/\\u/ 来找到你想要的文字\u

其次,您的(....) 组过于宽松,这将允许任何四个字符通过,这不是您想要的。在 1.9 中,您需要 (\h{4})(四个十六进制数字),但在 1.8 中,您需要 ([\da-fA-F]{4}),因为 \h 是一个新事物。

因此,如果您希望您的正则表达式同时在 1.8 和 1.9 中工作,您应该使用/\\u([\da-fA-F]{4})/。这在 1.8 和 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!"

使用 packunpack 将十六进制数字转换为 Unicode 字符可能已经足够了,但可能还有更好的方法。

【讨论】:

  • 将其添加为 String 类的扩展也很有用(我使用了 String#utf8_decode)。
猜你喜欢
  • 2012-01-28
  • 2012-03-03
  • 2018-10-31
  • 1970-01-01
  • 2021-01-30
  • 2014-02-28
  • 1970-01-01
  • 2011-12-02
  • 2013-09-26
相关资源
最近更新 更多