Это лучший способ отменить экранирование escape-последовательностей Unicode в Ruby? - PullRequest
7 голосов
/ 10 августа 2011

У меня есть текст, который содержит escape-последовательности Unicode, такие как \ u003C. Вот что я придумал, чтобы убрать это:

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

Это правильно? (то есть кажется, что он работает с моими тестами, но может ли кто-нибудь более знающий найти проблему с ним?)

1 Ответ

17 голосов
/ 11 августа 2011

У вашего регулярного выражения, /\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!"

Использование pack и unpack для преобразования шестнадцатеричного числа в символ Unicode, вероятно, достаточно хорошо, но могут быть и лучшие способы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...