Кодовая точка 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 без спецификации