解码或反转义 \u00f0\u009f\u0091\u008d 为

Decode or unescape \u00f0\u009f\u0091\u008d to

我们都知道 UTF-8 很难。我从 Facebook 导出消息,生成的 JSON 文件将所有非 ascii 字符转义为 unicode 代码点。

我正在寻找一种简单的方法来将这些 un​​icode 代码点转义为常规的旧 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++,我发现了这个 post:How to convert escaped Unicode (e.g. \u0432\u0441\u0435) to UTF-8 chars (все) in Notepad++。接受的答案也与上面的示例完全相同:ð.

我在这里找到了解码解决方案:UTF8.js library that decodes the text perfectly and you can try it out here(以 \u00f0\u009f\u0091\u008d 作为输入)。

PowerShell 中是否有解码 \u00f0\u009f\u0091\u008d 以接收的方法?我希望在导出的 Facebook 消息中使用真正的 UTF-8,这样我就可以真正阅读它们。

帮助我理解 \u00f0\u009f\u0091\u008d 实际代表什么的奖励积分(除了 some UTF-8 hex representation)。为什么和C++中的U+1F44D\uD83D\uDC4D一样?

该字符的 Unicode 代码点是 U+1F44D

使用可变长度的UTF-8编码,需要以下4个字节(表示为十六进制数字)来表示此代码点:F0 9F 91 8D

虽然这些字节在您的字符串中是可识别的,

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

它们不应表示为 \u 转义码,因为它们不是 Unicode 代码单元/代码点,它们是 字节 .

使用 4 位十六进制数字转义序列 (UTF-16),正确的表示需要 2 16 位 Unicode 代码 units,所谓的代理对,它们一起表示单个非 BMP 代码 point U+1F44D:

$str = "\uD83D\uDC4D"

如果您的 JSON 输入使用了此类正确的 Unicode 转义符,PowerShell 将正确处理该字符串;例如:

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

如果您检查文件 out.txt,您会看到如下内容:

str
---
 

(输出已发送到文件,因为控制台 windows 无法正确呈现字符,至少在没有额外配置的情况下不会;请注意,如果您使用 PowerShell Core 在 Linux 或 macOS 上,但是,终端输出可以工作。)


因此,最好的解决方案是从源头上解决问题并使用正确的 Unicode 转义符(或者甚至使用字符本身,只要源头支持任何标准 Unicode 编码)。

如果您真的必须解析损坏的表示,请尝试以下 解决方法 (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 ')).ForEach([byte])
  [text.encoding]::utf8.GetString($utf8Bytes)
})

这应该会产生 A for Motörhead.

以上将 \u... 转义序列转换为它们表示的字节值,并将生成的字节数组解释为 UTF-8 文本。


将解码后的字符串保存到 UTF-8 文件,请使用 ... | Set-Content -Encoding utf8 out.txt

或者,在 PSv5+ 中,正如 Dennis 自己建议的那样,您可以创建 Out-File,因此它是虚拟别名,>default 到 UTF-8通过 PowerShell 的全局参数默认哈希表:

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

但是请注意,在 Windows PowerShell(相对于 PowerShell Core)你会得到一个 UTF-8 文件 两种情况下的 BOM - 避免需要直接使用 .NET 框架:参见 Using PowerShell to write a file in UTF-8 without the BOM