Как мне декодировать строку с помощью экранированного юникода? - PullRequest
74 голосов
/ 25 октября 2011

Я не уверен, как это называется, поэтому у меня проблемы с поиском. Как я могу декодировать строку с Unicode от http\u00253A\u00252F\u00252Fexample.com до http://example.com с помощью JavaScript? Я попытался unescape, decodeURI и decodeURIComponent, поэтому я думаю, что единственное, что осталось, это заменить строку.

РЕДАКТИРОВАТЬ: строка не напечатана, а подстрока из другого фрагмента кода. Таким образом, чтобы решить проблему, вы должны начать что-то вроде этого:

var s = 'http\\u00253A\\u00252F\\u00252Fexample.com';

Надеюсь, это показывает, почему unescape () не работает.

Ответы [ 4 ]

104 голосов
/ 25 октября 2011

ОБНОВЛЕНИЕ : Обратите внимание, что это решение должно применяться к более старым браузерам или не браузерным платформам и поддерживается в учебных целях.Пожалуйста, обратитесь к ответу @radicand ниже для более актуального ответа.


Это экранированная строка в юникоде.Сначала строка была экранирована, затем закодирована с помощью Unicode.Чтобы преобразовать обратно в нормальное состояние:

var x = "http\\u00253A\\u00252F\\u00252Fexample.com";
var r = /\\u([\d\w]{4})/gi;
x = x.replace(r, function (match, grp) {
    return String.fromCharCode(parseInt(grp, 16)); } );
console.log(x);  // http%3A%2F%2Fexample.com
x = unescape(x);
console.log(x);  // http://example.com

Чтобы объяснить: я использую регулярное выражение для поиска \u0025.Однако, поскольку мне нужна только часть этой строки для операции замены, я использую скобки, чтобы выделить часть, которую я собираюсь использовать, 0025.Эта изолированная часть называется группой.

Часть gi в конце выражения обозначает, что она должна соответствовать всем экземплярам строки, а не только первому, и что сопоставление должно быть без учета регистра.Это может показаться ненужным, учитывая пример, но это добавляет универсальность.

Теперь, чтобы преобразовать одну строку в другую, мне нужно выполнить несколько шагов в каждой группе каждого соответствия, и я не могу этого сделатьпросто преобразовав строку.Полезно, что операция String.replace может принимать функцию, которая будет выполняться для каждого совпадения.Возвращение этой функции заменит само совпадение в строке.

Я использую второй параметр, который принимает эта функция, это группа, которую мне нужно использовать, и преобразовываю ее в эквивалентную последовательность utf-8, затем использую встроенную функцию unescape для декодирования строки вего правильная форма.

89 голосов
/ 13 октября 2012

Оригинальный ответ:

unescape(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"'));
> 'http://example.com'

Вы можете перенести всю работу на JSON.parse

Редактировать (2017-10-12) :

@ MechaLynx и @ Kevin-Weber отмечают, что unescape() устарела из не браузерной среды и не существует в TypeScript.decodeURIComponent является заменой.Для большей совместимости используйте нижеприведенное:

decodeURIComponent(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"'));
> 'http://example.com'
15 голосов
/ 03 ноября 2016

Обратите внимание, что использование unescape() устарело и не работает, например, с компилятором TypeScript.

На основе ответа Радиканда и раздела комментариев ниже, вот обновленное решение:

var string = "http\\u00253A\\u00252F\\u00252Fexample.com";
decodeURIComponent(JSON.parse('"' + string.replace(/\"/g, '\\"') + '"'));

http://example.com

2 голосов
/ 16 марта 2018

Мне не хватает представителя, чтобы добавить это к комментариям к существующим ответам:

unescape не рекомендуется использовать только для работы с URI (или любым кодированным utf-8), что, вероятно, соответствует потребностям большинства людей. encodeURIComponent преобразует строку js в экранированный UTF-8, а decodeURIComponent работает только в экранированных байтах UTF-8. Он выдает ошибку для чего-то вроде decodeURIComponent('%a9'); // error, потому что расширенный ascii недопустим utf-8 (хотя это все еще значение Юникода), тогда как unescape('%a9'); // © Так что вам нужно знать свои данные при использовании decodeURIComponent.

decodeURIComponent не будет работать на "%C2" или любом одиночном байте сверх 0x7f, потому что в utf-8 это указывает на часть суррогата. Однако decodeURIComponent("%C2%A9") //gives you © Unescape не будет работать должным образом на этом // © И не выдаст ошибку, поэтому unescape может привести к ошибочному коду, если вы не знаете свои данные.

...