有没有办法让printf / sprintf句柄正确组合字符?

时间:2015-02-16 16:51:14

标签: perl unicode printf

printfsprintf的计算中,组合字符似乎统计为整个字符:

[    é]
[   é]

上面的文字是由以下代码创建的:

#!/usr/bin/perl

use strict;
use warnings;

binmode STDOUT, ":utf8";

for my $s ("\x{e9}", "e\x{301}") {
        printf "[%5s]\n", $s; 
}

我希望打印代码:

[    é]
[    é]

在功能描述中,我没有看到任何关于Unicode的讨论,更不用说组合字符了。面对Unicode,printfsprintf是否无用?这只是Perl 5.20.1中可以修复的错误吗?是否有人写过替代品?

2 个答案:

答案 0 :(得分:4)

看起来答案是使用Unicode::GCString

#!/usr/bin/perl

use strict;
use warnings;

use Unicode::GCString;

binmode STDOUT, ":utf8";

for my $s ("\x{e9}", "e\x{301}", "e\x{301}\x{302}") {
        printf "[%s]\n", pad($s, 5);
}

sub pad {
        my ($s, $length) = @_;
        my $gcs = Unicode::GCString->new($s);
        return((" " x ($length - $gcs->columns)) . $s);
}

答案 1 :(得分:2)

你可能应该知道Perl Unicode Cookbook。特别是℞ #34,它涉及这个问题。作为奖励,Perl v5.20.2将其作为perldoc unicook提供。

无论如何:该文章中包含的代码如下:

use Unicode::GCString;
use Unicode::Normalize;

my @words = qw/crème brûlée/;
@words    = map { NFC($_), NFD($_) } @words;

for my $str (@words) {
    my $gcs  = Unicode::GCString->new($str);
    my $cols = $gcs->columns;
    my $pad  = " " x (10 - $cols);
    say str, $pad, " |";
}