首页 > 解决方案 > 解码或转义 \u00f0\u009f\u0091\u008d 到

问题描述

我们都知道 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++,我发现了这个 SO 帖子:How to convert escaped Unicode (eg \u0432\u0441\u0435) to UTF-8 chars (все) in Notepad++。接受的答案也与上面的示例完全相同:ð

我在这里找到了解码解决方案:完美解码文本的UTF8.js 库,您可以在这里尝试一下\u00f0\u009f\u0091\u008d作为输入)。

PowerShell中有没有办法解码\u00f0\u009f\u0091\u008d接收?我很想在我导出的 Facebook 消息中使用真正的 UTF-8,这样我才能真正阅读它们。

帮助我理解\u00f0\u009f\u0091\u008d实际代表什么的奖励积分(除了它是一些 UTF-8 十六进制表示)。为什么它与 C++ 相同U+1F44D\uD83D\uDC4D在 C++ 中?

标签: jsonfacebookpowershellutf-8facebook-messenger

解决方案


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

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

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

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

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

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

$str = "\uD83D\uDC4D"

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

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

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

str
---
 

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


因此,最好的解决方案是在源头纠正问题并使用正确的 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$1 ')).ForEach([byte])
  [text.encoding]::utf8.GetString($utf8Bytes)
})

这应该产生A for Motörhead.

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


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

或者,在 PSv5+ 中,正如 Dennis 自己所建议的那样,您可以通过 PowerShell 的全局参数默认哈希表将Out-File其设为虚拟别名>默认为 UTF-8:

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

但是请注意,在 Windows PowerShell(与 PowerShell Core相对)上,在这两种情况下,您都将获得一个带有 BOM的 UTF-8 文件- 避免这种情况需要直接使用 .NET 框架:请参阅使用 PowerShell 在没有 BOM 的 UTF-8


推荐阅读