Один хороший и быстрый хак использовать комбинацию encodeURI и: экранирования в
t=[];
for(s=unescape(encodeURI("zażółć gęślą jaźń")),i=0;i<s.length;++i)
t.push(s.charCodeAt(i));
t
[122, 97, 197, 188, 195, 179, 197, 130, 196, 135, 32, 103, 196, 153, 197, 155, 108, 196, 133, 32, 106, 97, 197, 186, 197, 132]
Возможно, какое-то объяснение необходимо, почему щеколда это работает, так что позвольте мне разбить его на этапы:
encodeURI("zażółć gęślą jaźń")
возвращается
"za%C5%BC%C3%B3%C5%82%C4%87%20g%C4%99%C5%9Bl%C4%85%20ja%C5%BA%C5%84"
который - если вы внимательно посмотрите - это исходная строка, в которой все символы со значениями> 127 заменены (возможно, несколькими) шестнадцатеричными представлениями байтов. Например, буква «ż» стала «% C5% BC». Дело в том, что encodeURI также выполняет некоторые обычные символы ascii, такие как пробелы, но это не имеет значения. Важно то, что в этот момент каждый байт исходной строки либо представлен дословно (как в случае с «z», «a», «g», или «j»), либо как процентная последовательность байтов (как и в случае с «ż», который был первоначально два байта 197 и 188 и преобразован в% C5 и% BC).
Теперь мы применяем экранирования в:
unescape("za%C5%BC%C3%B3%C5%82%C4%87%20g%C4%99%C5%9Bl%C4%85%20ja%C5%BA%C5%84")
, который дает
"zażóÅÄ gÄÅlÄ jaźÅ"
Если вы не родной польский спикер Вы не могли бы заметить, что этот результат на самом деле способ отличается от оригинала " zażółć gęślą jaźń ". Для начала у него разное количество символов :) Наверняка вы можете сказать, что эти странные версии большой буквы А не относятся к стандартному набору ascii. Фактически это «Å» имеет значение 197. (это точно C5 в шестнадцатеричном виде).
Теперь, если вы похожи на меня, вы спросите себя: подождите минуту ... если это действительно последовательность байтов со значениями 122, 97, 197, 188 и JS, на самом деле использует UTF, то почему Я вижу эти символы «¼», а не оригинальные «ż»?
Ну, дело в том (я верю), что эта последовательность 122, 97, 197, 188 (которые мы видим при применении charCodeAt) не является последовательность байтов , но последовательность кодов. Символ «Å» имеет код 197, но его фактически двухбайтная длинная последовательность: C3 85.
Итак, трюк работает, потому что unescape обрабатывает числа, происходящие в процентной кодировке, как коды, а не как байтовые значения - или, чтобы быть более конкретным: unescape ничего не знает о многобайтовых символах, поэтому, когда он декодирует байты один за другим, обработка значений ниже 128 просто отличная, но не очень хорошая, когда они выше 127 и многобайтовые - unescape в таких случаях просто возвращает многобайтовый символ, который имеет код, равный запрошенному значению байта. Эта «ошибка» на самом деле является полезной функцией.
Можете привести пример? – Gumbo
ASCII имеет * NO * значения> 128 (фактически, он не имеет значений> 127: он определяет коды от 0 до 127 включительно, ТОЛЬКО). Поэтому вопрос о «значениях ASCII> 128» не имеет смысла; вы должны означать некоторую другую кодировку символов (ISO-8859-x для некоторого значения x, может быть?) –
Имеются расширенные коды ASCII (от 128 до 255) http://www.asciitable.com/ –