Я не знаю, как это называется, поэтому у меня проблемы с поиском. Как я могу декодировать строку с помощью Unicode от http\u00253A\u00252F\u00252Fexample.com
до http://example.com
с помощью JavaScript? Я пробовал unescape
, decodeURI
и decodeURIComponent
поэтому думаю, что осталось только заменить строку.
РЕДАКТИРОВАТЬ: строка не вводится, а является подстрокой из другого фрагмента кода. Итак, чтобы решить проблему, вам нужно начать с чего-то вроде этого:
var s = 'http\\u00253A\\u00252F\\u00252Fexample.com';
Надеюсь, это показывает, почему unescape () не работает.
javascript
decode
urldecode
стиль
источник
источник
Ответы:
Изменить (2017-10-12) :
@MechaLynx и @ Kevin-Weber отмечают, что
unescape()
это не рекомендуется в средах, отличных от браузеров, и не существует в TypeScript.decodeURIComponent
это прямая замена. Для более широкой совместимости используйте вместо этого следующее:decodeURIComponent(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"')); > 'http://example.com'
Оригинальный ответ:
unescape(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"')); > 'http://example.com'
Вы можете переложить всю работу на
JSON.parse
источник
unescape(JSON.parse('"' + s + '"'));
чем причина лишних кавычек? Это делает его действительным JSON?fromCharCode
подход: jsperf.com/unicode-func-vs-json-parseJSON.parse('"' + s + '"')
при работе с ненадежными даннымиJSON.parse('"' + s.replace('"', '\\"') + '"')
, иначе ваш код сломается, когда ввод содержит кавычки.unescape()
он устарел,decodeURIComponent()
работает так же, какunescape()
в этом случае, поэтому просто замените его этим, и все будет хорошо.ОБНОВЛЕНИЕ : обратите внимание, что это решение, которое должно применяться к более старым браузерам или небраузерным платформам, и поддерживается в учебных целях. Пожалуйста, обратитесь к ответу @radicand ниже, чтобы получить более свежий ответ.
Это экранированная строка в кодировке Unicode. Сначала строка была экранирована, а затем закодирована с помощью 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
функцию для декодирования строки в ее правильную форму.источник
\u
префикс, а не четырехзначное шестнадцатеричное число (буквы или цифры). Как работает функция в методе замены?var r = /\\u([\d\w]{1,})/gi;
JSON.parse
подход: jsperf.com/unicode-func-vs-json-parseunescape()
может использоватьdecodeURIComponent()
вместо этого. В этом случае работает идентично. Однако я бы рекомендовал подход Radicand, поскольку он проще, так же поддерживается и быстрее выполняется с теми же результатами (однако обязательно прочтите комментарии).Обратите внимание, что использование
unescape()
не рекомендуется и, например, не работает с компилятором TypeScript.Основываясь на ответе подкоренного выражения и разделе комментариев ниже, вот обновленное решение:
var string = "http\\u00253A\\u00252F\\u00252Fexample.com"; decodeURIComponent(JSON.parse('"' + string.replace(/\"/g, '\\"') + '"'));
http://example.com
источник
У меня недостаточно репутации, чтобы поместить это в комментарии к существующим ответам:
unescape
устарел только для работы с URI (или любым закодированным utf-8), что, вероятно, подходит для нужд большинства людей.encodeURIComponent
преобразует строку js в экранированный UTF-8 иdecodeURIComponent
работает только с экранированными байтами UTF-8. Он выдает ошибку, например,decodeURIComponent('%a9'); // error
потому что расширенный ascii недействителен utf-8 (хотя это все еще значение Unicode), тогда какunescape('%a9'); // ©
вам нужно знать свои данные при использовании decodeURIComponent.decodeURIComponent не будет работать
"%C2"
ни с одним единственным байтом,0x7f
потому что в utf-8 указывается часть суррогата. ОднакоdecodeURIComponent("%C2%A9") //gives you ©
Unescape не будет работать с этим должным образом,// ©
И это не приведет к возникновению ошибки, поэтому unescape может привести к ошибочному коду, если вы не знаете свои данные.источник
Использование
JSON.decode
для этого имеет существенные недостатки, о которых вы должны знать:JSON.decode
(после упаковки их в двойных кавычках) будет ошибка , даже если они являются корректными:\\n
,\n
,\\0
,a"a
\\x45
\\u{045}
Есть и другие предостережения. По сути, использование
JSON.decode
для этой цели - это хитрость и не работает так, как вы всегда ожидали. Вам следует использоватьJSON
библиотеку для обработки JSON, а не для строковых операций.Недавно я сам столкнулся с этой проблемой и хотел получить надежный декодер, поэтому в итоге я написал его сам. Он полностью и тщательно протестирован и доступен здесь: https://github.com/iansan5653/unraw . Он максимально приближен к стандарту JavaScript.
Пояснение:
Источник составляет около 250 строк, поэтому я не буду включать его здесь все, но по сути он использует следующее регулярное выражение для поиска всех escape-последовательностей, а затем анализирует их, используя
parseInt(string, 16)
для декодирования чисел с основанием 16, а затемString.fromCodePoint(number)
для получения соответствующего символа:/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g
Прокомментировано (ПРИМЕЧАНИЕ. Это регулярное выражение соответствует всем escape-последовательностям, включая недопустимые. Если строка выдает ошибку в JS, она вызывает ошибку в моей библиотеке [то есть,
'\x!!'
будет ошибка]):/ \\ # All escape sequences start with a backslash (?: # Starts a group of 'or' statements (\\) # If a second backslash is encountered, stop there (it's an escaped slash) | # or x([\s\S]{0,2}) # Match valid hexadecimal sequences | # or u(\{[^}]*\}?) # Match valid code point sequences | # or u([\s\S]{4})\\u([^{][\s\S]{0,3}) # Match surrogate code points which get parsed together | # or u([\s\S]{0,4}) # Match non-surrogate Unicode sequences | # or ([0-3]?[0-7]{1,2}) # Match deprecated octal sequences | # or ([\s\S]) # Match anything else ('.' doesn't match newlines) | # or $ # Match the end of the string ) # End the group of 'or' statements /g # Match as many instances as there are
пример
Используя эту библиотеку:
import unraw from "unraw"; let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com'); // yields "http%3A%2F%2Fexample.com" // Then you can use decodeURIComponent to further decode it: let step2 = decodeURIComponent(step1); // yields http://example.com
источник