解码或反转义 \u00f0\u009f\u0091\u008d 为
Decode or unescape \u00f0\u009f\u0091\u008d to
我们都知道 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++,我发现了这个 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
我们都知道 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++,我发现了这个 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