【问题标题】:Decode or unescape \u00f0\u009f\u0091\u008d to ????将 \u00f0\u009f\u0091\u008d 解码或转义为 ????
【发布时间】:2018-06-12 22:38:07
【问题描述】:

我们都知道 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 (e.g. \u0432\u0441\u0435) to UTF-8 chars (все) in Notepad++。接受的答案也与上面的示例完全相同:ð.

我在这里找到了解码解决方案:完美解码文本的UTF8.js library,您可以使用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 代码点...从 unicode.org 网站查看标准。

标签: json facebook powershell utf-8 facebook-messenger


【解决方案1】:

?字符的 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
---
? 

(输出已发送到文件,因为控制台窗口无法正确呈现 ?char。至少在没有额外配置的情况下不会;请注意,如果您在 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 设为虚拟别名 >default 为 UTF-8:

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

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

【讨论】:

    猜你喜欢
    • 2019-06-01
    • 2018-09-06
    • 2021-07-01
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多