如何在Perl中格式化输出?

时间:2012-11-07 14:41:34

标签: perl text formatting

我有一个负责格式化输出的Perl代码。问题是我需要在每个字符串中的一个特定字符之前计算要放置的正确数量的标签(让我们说它是' s /)。因此,我不想获得不同长度的线条,而是希望获得固定长度的字符串(但尽可能短,使用最长的字符串)。我该怎么做呢?

输出示例(格式已注释掉,只是原始数组):

Long title with some looong words / short text
Another title / another short text

我需要这样:

title with some looong words / short text
Different title              / another short text

这是我的第一次尝试,但它没有涉及在一个特定角色后使用制表符。

my $text = Text::Format->new;

$text->rightAlign(1);
$text->columns(65);
$text->tabstop(4);

$values[$i] = $text->format(@values[$i]);

3 个答案:

答案 0 :(得分:2)

在Perl中有两种普遍接受的格式化文本的方法,因此列排列:

  • 使用printfsprintf。这可能是最常见的方式。
  • 使用Perl Format功能。您可以定义行的外观,然后使用write打印到该格式。

我没有看到人们多年来使用Perl Format规范的东西。这是Perl 3.x全盛时期的一大特色,因为Perl主要用作超级awk替代语言( P ractical E 提取和 R eporting L anguage)。但是,机制仍然存在,我相信学习会很有趣。


现在是查询的第二部分。你真的不仅希望对文本进行格式化,而是希望 使用标签 进行格式化。

幸运的是,Perl有一个名为Text::Tabs的内置模块。这是执行一两个模糊任务的模块之一,但做得很好。

实际上,Text::Tabs并不能很好地处理它做得好的两项任务。

使用sprintf或内置的Perl格式化功能生成报告。将整个报表保存在一个数组中。它必须是一个数组,因为Text::Tabs不处理NL。然后使用unexpand函数将该数组中的空格替换为带有制表符的另一个数组。

WORD'O WARNING Text::Tabs做一些非常顽皮的事情:它会将变量$tabstop导入您的程序而不征得您的许可。如果您使用名为$tabstop的变量,则必须更改它。您可以将$tabstop设置为选项卡表示的空格数。它默认设置为8。

答案 1 :(得分:0)

模块Text::Table可能会对您有所帮助。

#!/usr/bin/perl
use warnings;
use strict;

use Text::Table;

my @array = ('Long title with some looong words', 'short text',
             'Another title',                     'another short text');

my $table = Text::Table::->new(q(), \' / ', q()); # Define the separator.
$table->add(shift @array, shift @array) while @array;
print $table;

答案 2 :(得分:0)

从文档中我可以找到Text :: Format只进行段落格式化。你想要的是表格格式。基本方法是将数据拆分为每行的文本矩阵。列,找到每列的最长元素,并使用它输出固定宽度数据。 e.g:

my @values = (
    'Long title with some looong words / short text',
    'Another title / another short text',
);

# split values into per-column text
my @text = map { [ split '\s*(/)\s*', $_ ] } @values;

# find the maximum width of each column
my @width;
foreach my $line (@text) {
    for my $i (0 .. $#$line) {
        no warnings 'uninitialized';
        my $l = length $line->[$i];
        $width[$i] = $l if $l > $width[$i];
    }
}

# build a format string using column widths
my $format = join ' ', map { "%-${_}s" } @width;
$format .= "\n";

# print output in columns
printf $format, @$_ foreach @text;

这会产生以下结果:

Long title with some looong words / short text        
Another title                     / another short text