为什么会打印U
而不是Ü
?
#!/usr/bin/env perl
use warnings;
use 5.014;
use utf8;
binmode STDOUT, ':utf8';
use charnames qw(:full);
my $string = "\N{LATIN CAPITAL LETTER U}\N{COMBINING DIAERESIS}";
while ( $string =~ /(\X)/g ) {
say $1;
}
# Output: U
答案 0 :(得分:8)
您的代码是正确的。
你真的需要用数字来玩这些东西;不要相信“终端”显示的内容。通过the uniquote program管道,可能是-x
或-v
,看看它到底在做什么。
眼睛欺骗,节目更糟糕。你的终端程序有问题,所以对你撒谎。规范化无关紧要。
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say "crème brûlée"'
crème brûlée
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say "crème brûlée"' | uniquote -x
cr\x{E8}me br\x{FB}l\x{E9}e
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFD "crème brûlée"'
crème brûlée
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFD "crème brûlée"' | uniquote -x
cre\x{300}me bru\x{302}le\x{301}e
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFC scalar reverse NFD "crème brûlée"'
éel̂urb em̀erc
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFC scalar reverse NFD "crème brûlée")' | uniquote -x
\x{E9}el\x{302}urb em\x{300}erc
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say scalar reverse NFD "crème brûlée"'
éel̂urb em̀erc
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say scalar reverse NFD "crème brûlée"' | uniquote -x
e\x{301}el\x{302}urb em\x{300}erc
答案 1 :(得分:3)
这适用于我,虽然我在ubuntu上有一个旧版本的perl 5.012
。我对您的脚本的唯一更改是:use 5.012;
$ perl so.pl
Ü
答案 2 :(得分:1)
我可以建议输出不正确吗?这很容易检查:用以下代码替换你的循环代码:
my $counter;
while ( $string =~ /(\X)/g ) {
say ++$counter, ': ', $1;
}
...并查看正则表达式匹配的次数。我的猜测它仍然只会匹配一次。
或者,您可以使用此代码:
use Encode;
sub codepoint_hex {
sprintf "%04x", ord Encode::decode("UTF-8", shift);
}
...然后在while循环中打印codepoint_hex($ 1)而不是普通的$ 1。
答案 3 :(得分:1)
1)显然,您的终端无法显示扩展字符。在我的终端上,它打印出来:
U¨
2) \X
没有按照您的想法行事。它只选择一起出现的角色。如果您使用字符串"fu\N{COMBINING DIAERESIS}r"
,程序将显示:
f
u¨
r
请注意,变音符号不是单独打印,而是以其相应的字符打印。
3)要将所有相关字符合并为一个,请使用模块Unicode::Normalize:
use Unicode::Normalize;
my $string = "fu\N{COMBINING DIAERESIS}r";
$string = NFC($string);
while ( $string =~ /(\X)/g ) {
say $1;
}
显示:
f
ü
r