2011-08-10 16 views
7

我有一些包含Unicode轉義序列(如\ u003C)的文本。這是我想出了要取消轉義它:這是在ruby中使用unicode轉義序列的最佳方式嗎?

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

它是正確的嗎? (即它似乎與我的測試一起工作,但是可以有人更熟悉它發現問題嗎?)

+0

你是對的。它來自Rails的ActiveSupport :: JSON,並被ActiveSupport :: JSON解碼,但它不能正確解碼\ u轉義。 (在Rails 2.1.2上) –

回答

17

您的正則表達式,/\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字符可能是不夠好,但有可能是更好的方法。

+1

將此作爲String類的擴展添加(我使用String#utf8_decode)也很有用。 – Mikey