Расшифровать или удалить с экрана to00f0 \ u009f \ u008d до ? - PullRequest
0 голосов
/ 13 июня 2018

Мы все знаем, что UTF-8 сложно.Я экспортировал свои сообщения из Facebook, и полученный файл JSON экранировал все символы, отличные от ascii, в кодовые точки Unicode.

Я ищу простой способ отменить эти кодовые точки Unicode для обычного старого UTF-8.Я также хотел бы использовать PowerShell.

Я пытался

$str = "\u00f0\u009f\u0091\u008d"
[Regex]::Replace($str, "\\[Uu]([0-9A-Fa-f]{4})", `
{[char]::ToString([Convert]::ToInt32($args[0].Groups[1].Value, 16))} )

, но в результате я получил только Р , а не ?.

Я также попытался использовать Notepad ++, и я нашел этот пост SO: Как преобразовать экранированный Unicode (например, \u0432\u0441\u0435) в символы UTF-8 (все) в Notepad ++ .Принятый ответ также приводит к тому же результату, что и в примере выше: ð .

Я нашел решение для декодирования здесь: библиотека UTF8.js , которая декодирует текстотлично, и вы можете попробовать здесь \u00f0\u009f\u0091\u008d в качестве ввода).

Есть ли способ в PowerShell декодировать \u00f0\u009f\u0091\u008d для получения to?Я бы хотел иметь настоящий UTF-8 в моих экспортированных сообщениях Facebook, чтобы я мог их прочитать.

Бонусные баллы за помощь в понимании того, что на самом деле представляет \u00f0\u009f\u0091\u008d (кроме того, что некоторый UTF-8 шестнадцатеричное представление ).Почему это так же, как U+1F44D или \uD83D\uDC4D в C ++?

1 Ответ

0 голосов
/ 13 июня 2018

Кодовая точка Unicode ?character составляет U+1F44D.

При использовании кодировки UTF-8 переменной длины следующие 4 байтов (выраженышестнадцатеричные числа) необходимы для представления этой кодовой точки: F0 9F 91 8D.

Хотя эти байты распознаются в вашей строке,

$str = "\u00f0\u009f\u0091\u008d"

они не должны быть представленыкак \u escape-коды, поскольку они не являются единицами кода Unicode / кодовой точкой, они байтов .

с escape-последовательностью из 4 шестнадцатеричных цифр (UTF-16), для правильного представления потребуется 2 16-битный код Unicode единиц , так называемая суррогатная пара, которые вместе представляют один не-BMP код point U+1F44D:

$str = "\uD83D\uDC4D"

Если ваш ввод JSON использует такие правильные экранированные символы Юникода, PowerShell правильно обработает строку;Например:

'{ "str": "\uD83D\uDC4D" }' | ConvertFrom-Json > out.txt

Если вы изучите файл out.txt, вы увидите что-то вроде:

str
---
? 

(Вывод был отправлен в файл, потому что консольные окна не будутотразите ?char. правильно, по крайней мере, без дополнительной настройки; обратите внимание, что если вы используете PowerShell Core в Linux или macOS, вывод терминала будет работать.)


Поэтому, лучшим решением было бы исправить проблему в источнике и использовать надлежащие экранированные символы Юникода (или даже использовать сами символы, если источник поддерживает любую из стандартных кодировок Юникода).

Если вам действительно нужно проанализировать некорректное представление, попробуйте следующий обходной путь (PSv4 +), опираясь на собственную [regex]::Replace() методику:

$str = "A \u00f0\u009f\u0091\u008d for Mot\u00c3\u00b6rhead."

[regex]::replace($str, '(?:\\u[0-9a-f]{4})+', { param($m) 
  $utf8Bytes = (-split ($m.Value -replace '\\u([0-9a-f]{4})', '0x$1 ')).ForEach([byte])
  [text.encoding]::utf8.GetString($utf8Bytes)
})

Это должно дать A ? for Motörhead.

Приведенное выше преобразование последовательностей \u... экранирует в значения байтов, которые они представляют, и интерпретирует полученный байтовый массив как текст UTF-8.


В сохраните декодированную строку вфайл UTF-8 , используйте ... | Set-Content -Encoding utf8 out.txt

В качестве альтернативы, в PSv5 +, как предполагает сам Деннис, вы можете сделать Out-File и, следовательно, его виртуальный псевдоним, >, по умолчанию в UTF-8 через хеш-таблицу глобальных значений параметров по умолчанию для PowerShell:

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'

Однако обратите внимание, что в Windows PowerShell (в отличие от PowerShell Core ) вы получите UTF-8 файл с спецификацией в обоих случаях - во избежание этого требуется непосредственное использование .NET Framework: см. Использование PowerShell для записи файла в UTF-8 без спецификации

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