是的,我知道所有版本的printf
都存在问题,我在 Unicode:: GCString a > 模块表 CPAN 来计算 Unicode 字符串将包含的打印栏数 。 这考虑到了 < a href=" http://unicode. org/reports/ tr11/ " rel=" nofolncode noreferr" > Unicode 标准附件 # 11: 东亚 Width 。
例如,有些代码点取一列,而另一些则取两列。甚至有些代码点也取不取任何列,例如将字符和无形控制字符结合起来。该类使用 columns
方法返回字符串取取的列数。
我有一个用于垂直对齐 Unicode 文本的示例 : < a href=" http://training.perl.com/ scripts/perlunicook.html#PROGRAM:- Demo-of- Unicode-corration-corration-and-printing" rel = “ nofollow noreferrerr" > here 。 它将排序一连串 Unicode 字符, 包括一些包含字符和“ 范围” 亚洲的“ idegraphics (CJK 字符) 的字符, 并允许您垂直对齐 。
"https://i.sstatic.net/ifmnX.png" alt="sample终端输出"/ >
以下列出了小 umenu
演示程序代码,该代码打印出与输出相近的精准输出。
您也可能感兴趣的是远为雄心勃勃的“http://search.cpan.org/perldoc?Unicode% 3a% 3aLineBreak” rel=“不跟随Noreferr”>Unicode:::LineBreak 模块,上述 Unicode::GCString
类只是一个较小的组成部分。这个模块更酷,并且考虑到 Unicode 标准附件#14:Unicode 线破解 Algorithm 。
这是在 Perl v5.14 中测试的小 < code> umenu 演示的代码 :
#!/usr/bin/env perl
# umenu - demo sorting and printing of Unicode food
#
# (obligatory and increasingly long preamble)
#
use utf8;
use v5.14; # for locale sorting
use strict;
use warnings;
use warnings qw(FATAL utf8); # fatalize encoding faults
use open qw(:std :utf8); # undeclared streams in UTF-8
use charnames qw(:full :short); # unneeded in v5.16
# std modules
use Unicode::Normalize; # std perl distro as of v5.8
use List::Util qw(max); # std perl distro as of v5.10
use Unicode::Collate::Locale; # std perl distro as of v5.14
# cpan modules
use Unicode::GCString; # from CPAN
# forward defs
sub pad($$$);
sub colwidth(_);
sub entitle(_);
my %price = (
"γύρος" => 6.50, # gyros, Greek
"pears" => 2.00, # like um, pears
"linguiça" => 7.00, # spicy sausage, Portuguese
"xoriço" => 3.00, # chorizo sausage, Catalan
"hamburger" => 6.00, # burgermeister meisterburger
"éclair" => 1.60, # dessert, French
"smørbrød" => 5.75, # sandwiches, Norwegian
"spätzle" => 5.50, # Bayerisch noodles, little sparrows
"包子" => 7.50, # bao1 zi5, steamed pork buns, Mandarin
"jamón serrano" => 4.45, # country ham, Spanish
"pêches" => 2.25, # peaches, French
"シュークリーム" => 1.85, # cream-filled pastry like éclair, Japanese
"막걸리" => 4.00, # makgeolli, Korean rice wine
"寿司" => 9.99, # sushi, Japanese
"おもち" => 2.65, # omochi, rice cakes, Japanese
"crème brûlée" => 2.00, # tasty broiled cream, French
"fideuà" => 4.20, # more noodles, Valencian (Catalan=fideuada)
"pâté" => 4.15, # gooseliver paste, French
"お好み焼き" => 8.00, # okonomiyaki, Japanese
);
my $width = 5 + max map { colwidth } keys %price;
# So the Asian stuff comes out in an order that someone
# who reads those scripts won t freak out over; the
# CJK stuff will be in JIS X 0208 order that way.
my $coll = new Unicode::Collate::Locale locale => "ja";
for my $item ($coll->sort(keys %price)) {
print pad(entitle($item), $width, ".");
printf " €%.2f
", $price{$item};
}
sub pad($$$) {
my($str, $width, $padchar) = @_;
return $str . ($padchar x ($width - colwidth($str)));
}
sub colwidth(_) {
my($str) = @_;
return Unicode::GCString->new($str)->columns;
}
sub entitle(_) {
my($str) = @_;
$str =~ s{ (?=pL)(S) (S*) }
{ ucfirst($1) . lc($2) }xge;
return $str;
}
正如你所看到的,让它在这个特定方案中发挥作用的关键 就是这行代码, 它只是呼唤上面定义的其他功能, 并使用我正在讨论的模块:
print pad(entitle($item), $width, ".");
这将用点作为填充字符将项目插入给定宽度。
是的,printf
的方便程度要低得多,但至少是可能的。