如何使用Term::ANSIColor
正确左对齐(在固定长度的字段内)一个颜色字符串?这是一个示例程序:
use strict;
use warnings;
use Term::ANSIColor;
my $str1 = "Hello";
my $str2 = (color("bold red") . $str1 . color("reset"));
printf "%-10s : ok\n", $str1;
printf "%-10s : ok\n", $str2;
输出:
预期输出:我希望"ok"
字段垂直对齐。
答案 0 :(得分:3)
问题在于,当您向str2添加颜色时,它会在设置颜色的单词之前将字符串作为前缀加上字符,然后在单词后面加上字符以重置颜色。当你打印这些时,你当然不会看到这些额外的字符。当你的shell解释它们并只打印你选择的颜色的字符串文本。
我们可以在这里看到每个字符串的长度。
use strict;
use warnings;
use Term::ANSIColor;
my $str1 = "Hello";
my $str2 = (color("bold red") . $str1 . color("reset"));
print "length of str1 is: ", length($str1), "\n";
print "length of str2 is: ", length($str2), "\n";
printf "%-10s : ok\n", $str1;
printf "%-10s : ok\n", $str2;
<强>输出强>
length of str1 is: 5
length of str2 is: 16
Hello : ok
Hello : ok
当printf
评估$str2
的长度时,它会将其视为16,因为它大于10,所以它不需要用任何空格填充它。
正如@tjd在评论中所说,你需要重新思考你的方法,把颜色放在格式中,而不是把它放在数据中自己
答案 1 :(得分:2)
执行此操作的一种方法是在 printf
之后而不是之前应用颜色序列:
use strict;
use warnings;
use 5.010;
use Term::ANSIColor;
my $format = '%-10s';
my @greetings = (
sprintf($format, 'Hello'),
sprintf($format, 'Greetings')
);
foreach my $greeting (@greetings) {
say colored($greeting, 'bold red') . ' : ok';
say "$greeting : ok";
}
Hello : ok
Hello : ok
Greetings : ok
Greetings : ok
(第一个Hello
和第一个Greetings
颜色,当然)
您还可以使用Text::Aligner
,它知道如何解释由Term::ANSIColor
生成的颜色序列:
use strict;
use warnings;
use 5.010;
use Term::ANSIColor;
use Text::Aligner qw(align);
my @greetings = qw(Hello Greetings);
my @lines;
foreach my $greeting (@greetings) {
push @lines, colored($greeting, 'bold red') . ' : ok';
push @lines, "$greeting : ok";
}
say for align(qr/:/, @lines);
Hello : ok
Hello : ok
Greetings : ok
Greetings : ok
(同样,第一个Hello
和第一个Greetings
颜色)
请注意,这会对冒号中的所有内容进行对齐,因此您不会获得所要求的左对齐输出,但这是另一种思考方式。