2011-08-10 4 views
7

私は\ u003CのようなUnicodeエスケープシーケンスを含むテキストをいくつか持っています。これは私がそれをアンエスケープするために思い付いたものです:これは、Rubyでユニコードのエスケープシーケンスをエスケープする最良の方法ですか?

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

は、それが正しいですか? (つまり、私のテストではうまくいくようですが、知識のある人がそれに問題を見つけることができますか?)

+0

そうです。それはRailsのActiveSupport :: JSONから来て、ActiveSupport :: JSONによってデコードされていますが、\ escapeを正しくデコードしていません。 (on Rails 2.1.2) –

答えて

17

正規表現/\u(....)/にはいくつか問題があります。すべての

まず、\uあなたはそれが、1.9にエラーを取得しますないと1.8にそれだけではなく、あなたが探している\uペアよりも、単一uにマッチすると思うように動作しません。 \uを見つけるには/\\u/を使用してください。

第2に、あなたの(....)グループはあまりにも許容性があり、それは4文字を通り抜けることができ、それはあなたが望むものではありません。 1.9では、(\h{4})(4桁の16進数)が必要ですが、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!" 

Unicode文字に進数をマングルするpackunpackを使用して、おそらく十分ですが、より良い方法があるかもしれません。

+1

これをStringクラスの拡張として追加すると便利です(私はString#utf8_decodeを使用しました)。 – Mikey

関連する問題