提问人:WingedKnight 提问时间:6/9/2022 最后编辑:WingedKnight 更新时间:6/9/2022 访问量:202
如何使用 Perl 包将 UTF-16 代理项对转换为 UTF-8?
How to use Perl pack to convert UTF-16 surrogate pairs to UTF-8?
问:
我有输入字符串,其中包含一些字符采用 UTF-16 格式并用“”转义的文本。我正在尝试在 Perl 中将所有字符串转换为 UTF-8。例如,字符串在输入中的格式可能为:\u
'Alice & Bob & Carol'
'Alice \u0026 Bob \u0026 Carol'
为了做我想要的转换,我正在做...:
$str =~ s/\\u([A-Fa-f0-9]{4})/pack("U", hex($1))/eg;
...在我输入包含 UTF-16 代理项对的字符串之前,它工作正常,例如:
'Alice \ud83d\ude06 Bob'
如何修改上述用于处理 UTF-16 代理项对的代码?我真的想要一个无需使用任何其他库(JSON::XS、Encode 等)即可使用的解决方案。pack
pack
答:
3赞
Shawn
6/9/2022
#1
pack
/unpack
对 UTF-16 文本一无所知,只了解 UTF-8(和 UTF-EBCDIC)。您必须手动解码代理项对,因为您不想使用模块。
#!/usr/bin/env perl
use strict;
use warnings;
use open qw/:locale/;
use feature qw/say/;
my $str = 'Alice \ud83d\ude06 Bob \u0026 Carol';
# Convert surrogate pairs encoded as two \uXXXX sequences
# Only match valid surrogate pairs so adjacent non-pairs aren't counted as one
$str =~ s/\\u((?i)D[89AB]\p{AHex}{2}) # High surrogate in range 0xD800–0xDBFF
\\u((?i)D[CDEF]\p{AHex}{2}) # Low surrogate in range 0xDC00–0xDFFF
/chr( ((hex($1) - 0xD800) * 0x400) + (hex($2) - 0xDC00) + 0x10000 )/xge;
# Convert single \uXXXX sequences
$str =~ s/\\u(\p{AHex}{4})/chr hex $1/ge;
say $str;
输出
Alice 😆 Bob & Carol
评论
0赞
ikegami
6/9/2022
我会反其道而行之。解码 ,然后查找 。以这种方式适用于更多输入。\u
[\x{D800}-\x{DBFF}][\x{DC00}-\x{DFFF}]
0赞
Shawn
6/9/2022
以这种方式对无效字符的警告太多。
0赞
ikegami
6/9/2022
回复“Too many warnings about invalid characters that way.”,您可能没有从 to 进行必要的伴随更改。hex($x)
ord($x)
0赞
ikegami
6/9/2022
该解决方案不适用于{ "a": "\\u2660" }
1赞
WingedKnight
6/10/2022
@ikegami:如果你认为你有更好的解决方案,那么你能发布代码来证明你的解决方案作为答案吗?谢谢。
评论
ord
unpack W
chr
pack W