7

为什么这会打印 aU而不是 a Ü

#!/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
4

4 回答 4

8

你的代码是正确的。

你真的需要用数字来玩这些东西;不要相信“终端”显示的内容。将它通过uniquote程序(可能使用or )进行管道传输,看看它到底在做什么。-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
于 2012-02-24T12:02:25.760 回答
3

这对我有用,尽管我5.012在 ubuntu 上有一个旧版本的 perl, 。我对您的脚本的唯一更改是:use 5.012;

$ perl so.pl 
Ü
于 2012-02-24T10:38:51.797 回答
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 。

于 2012-02-24T10:49:40.217 回答
1

1)显然,您的终端无法显示扩展字符。在我的终端上,它打印:

2) \X没有做你认为它做的事情。它只是选择一起出现的字符。如果您使用 string "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
于 2012-02-24T10:51:22.023 回答