解码或unescape \ u00f0 \ u009f \ u009 \ u008d to

时间:2018-06-12 22:38:08

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

我们都知道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 ++,我发现了这个帖子: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相同?

1 个答案:

答案 0 :(得分:4)

角色的Unicode代码点为U+1F44D

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

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

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

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

使用4-hex-digit转义序列(UTF-16),正确的表示将需要 2 16位Unicode代码单位,即所谓的代理对,它们一起代表单个非BMP代码 point U+1F44D

$str = "\uD83D\uDC4D"

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

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

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

str
---
 

(输出已发送到文件,因为控制台窗口无法正确呈现char。至少在没有其他配置的情况下;请注意,如果您在Linux上使用PowerShell Core 或但是,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$1 ')).ForEach([byte])
  [text.encoding]::utf8.GetString($utf8Bytes)
})

这应该产生A for Motörhead.

上面将\u...转义的序列转换为它们所代表的字节值,并将结果字节数组解释为UTF-8文本。

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

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

$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