我们都知道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
相同?
答案 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