【问题标题】:How to write wrapped table format in Perl如何在 Perl 中编写包装表格式
【发布时间】:2013-01-22 23:26:55
【问题描述】:

我正在用 Perl 编写以表格格式显示我的报告,但是每当数据填充的文本太长时我就会遇到问题。有没有办法编写代码,以便它可以将行包装成多个。这是我的代码和输出。谢谢!

printf "\n%-${max1}s %-${max2}s %-15s\n", "====", "====", "=====" ;
printf "%-${max1}s %-${max2}s %-15s\n", "Code", "Item", "Group" ;
printf "%-${max1}s %-${max2}s %-15s\n", "====", "====", "=====" ;

foreach my $f (@{$rpt_ptr}) {
printf "%-${max1}s %-${max2}s %-15s\n", "$$f{code}", "$$f{item}", "$$f{group}", 
}

如果我的项目列表太长,输出表将被延长太长,即:-

====  =====                                                                                =====      

Code  Item                                                                                 Group

====  =====                                                                                =====

A1011 aaaaaa, bbbbb, ccccc, ddddd, eeeee, fffff, ggggg, hhhhh, iiiii, jjjjjj, kkkkk, llll    B
    B101  cccccc                                                                                 A

如果我能拿出一张这样的桌子,我会很高兴:

====  =====                                                                                =====      
Code  Item                                                                                 Group
====  =====                                                                                =====
A1011 aaaaaa, bbbbb, ccccc, ddddd,                                                           B
      eeeee, fffff, ggggg, hhhhh,   
      iiiii, jjjjjj, kkkkk, llll
B101  cccccc                                                                                 A

我将如何实现这一目标?

【问题讨论】:

    标签: perl


    【解决方案1】:

    Perl 最初是为格式化文本文件而编写的。它包括一个相当有趣的表单生成工具,包括按照您指定的方式换行的能力。我很久很久没有看到它使用了,但它仍然是语言的一部分。

    它在 perlform 下的 Perldoc 中。


    示例

    #! /usr/bin/env perl
    
    use strict;
    use warnings;
    use feature qw(say);
    
    my ($invoice, $description, $amount);
    while ( chomp ( my $line = <DATA> ) ) {
        ( $invoice, $description, $amount ) = split /:/ => $line;
        write;
    }
    
    format STDOUT_TOP =
    Invoice   Description       Amount
    =======   ===========       =======
    .
    format STDOUT = 
    @<<<<<<   ^<<<<<<<<<<<<<<   @###.##
    $invoice, $description,     $amount
              ^<<<<<<<<<<<<<<
              $description
              ^<<<<<<<<<<<<<<
              $description
              ^<<<<<<<<<<<<<<
              $description
              ^<<<<<<<<<<<<<<
              $description
    .
    __DATA__
    One:This line contans a lot of text that I have to process and I have no idea what it is:2.30
    Two:Here's another line that contains lots of data that won't fit on a single line:4.40
    Three:And one more line of extra long data that may or may not fit on a single line:5.10
    

    输出

    Invoice   Description       Amount
    =======   ===========       =======
    One       This line            2.30
              contans a lot
              of text that I
              have to process
              and I have no
    Two       Here's another       4.40
              line that
              contains lots
              of data that
              won't fit on a
    Three     And one more         5.10
              line of extra
              long data that
              may or may not
              fit on a single
    

    【讨论】:

    • W,谢谢,我已经查看了您提供的链接,但有些我仍然无法完成它。一个示例代码对我会更有帮助。
    • 我认为它也是 Perl 编程书籍的一部分,尽管它几乎没有被使用过。
    • @Grace 我在答案中添加了一个示例。我遇到的唯一问题是我必须在循环外声明我的局部变量才能让我的格式语句看到变量。很快就弄清楚了。
    • @vol7ron 和所有人,感谢您的帮助和示例编码。我终于解决了我的prblm,并分享了我的编码如下。我勾选了提供最接近解决方案的大卫。再次感谢大家!
    • @DavidW。您的格式效果很好,但是使用这种格式,$description 显示的行数是固定的(5 行),所以如果我的字符串比那个长,它会被截断,如果短于 5 行,总会有是正在显示的空行。如果内容太长并且即使内容很短也没有尾随空行,有什么方法可以完全显示内容?谢谢!
    【解决方案2】:

    formats 确实是正确的选择。

    这是使用Perl6::Form的解决方案:

    use Perl6::Form;
    
    my @data = (
        ['A1011', 'aaaaaa, bbbbb, ccccc, ddddd, eeeee, fffff, ggggg, hhhhh, iiiii, jjjjjj, kkkkk, llll', 'B'],
        ['B101', 'cccccc', ''],
    );
    
    print form
        "====  =====                                              =====",
        "Code  Item                                               Group",
        "====  =====                                              =====";
    
    foreach (@data) {
        print form
            "{<<<<}{[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[}             {<<}", @$_ ;
    }
    

    【讨论】:

    • 这也在核心 Perl 5 库中。 Perl6::Form 和标准的有什么区别?它们看起来很相似。诚然,我已经有 mumble mumble 年没有玩过表格了。只是好奇这些差异。
    • @stevenl,谢谢,但我的系统不支持 Perl6,我们使用的是为 x86_64-linux 构建的 v5.8.5,它也不支持 form.pm。如果我不允许复制模块,有什么解决方案吗?实际上,输入数据的填充是不固定的。我将为该列取消引用值。我为我的原始编码添加了 foreach 循环(用于表格数据填充)。
    • @Grace 5.8 是古老的。你真的应该至少 5.12(最低 5.10)
    • 没有选择,除非管理员更新,但据我所知,没有决定更新。
    • @Grace Perl6::Form 是一个 Perl 5 模块,应该可以在 v5.8.5 中正常工作
    【解决方案3】:

    您可以使用正则表达式来包装文本。 由于您正在逐行打印文件, 您可以获取标量变量中的每一行并检查该标量变量的长度并插入换行符\n

    喜欢:

        $var = "\n%-${max1}s %-${max2}s %-15s\n", "====", "====", "=====" ;
        $var .= "%-${max1}s %-${max2}s %-15s\n", "Code", "Item", "Group" ;
        $var .= "%-${max1}s %-${max2}s %-15s\n", "====", "====", "=====" ;
    
        ## Adding new line character after 20 characters.
        my $startIndex = 0;
    
        while( ($startIndex < length($var) && (length($var) > 20) ) {
         print substr($var, $startIndex, 20)  . "\n";
         $startIndex = $startIndex + 20;
        }
    

    【讨论】:

    • 感谢您的代码,我试过了,但它不适合我。我已经修改了表格输入的原始代码,这将是上面标题之后的数据。我仍然无法完成它:(
    【解决方案4】:

    如果您想要一些非常基本/特定的内容(不可靠),请每隔四个逗号强制换行:

    printf之前的循环中:

    $$f{item} =~ s/(,[^,]+,[^,]+,[^,]+,)/$1\n/g;
    

    最好的选择可能是按照 David 的建议使用 perlform (5.8.8 for you)

    【讨论】:

    • 你能给我写个样本吗?我需要输入字段能够从取消引用值中读取,尽管需要将其拆分为多行。每当看到“,”时就打破界限对我来说是不切实际的。谢谢。
    • @Grace:阅读表单部分的顶部。当其他人已经有的时候,我不会写一个例子。您必须实际阅读文档
    • 这是另一个问题的示例:stackoverflow.com/a/3329743/183181
    • 你可能会错过它,所以这里有一个链接到更好的tutorial 来自答案。
    • 感谢链接和参考教程,但我仍然无法完成它。它打印出某种缩进错误的格式并改变了输出:(。
    【解决方案5】:

    我终于通过下面的代码完成了,贴在这里分享:-

    foreach my $f (@{$rpt_ptr}) {
    #   printf "%-${max1}s %-${max2}s %-15s\n", "$$f{code}", "$$f{item}", "$$f{group}", 
    format STDOUT_TOP =
    ===============     =========================     ========= 
    Code                 Item                     Group
    ===============     =========================     ========= 
    .
    
    format STDOUT =
    @<<<<<<<<<<<<<<     ^<<<<<<<<<<<<<<<<<<<<<<<<<     @<<<<<<<<
    $$f{code}               $$f{item}                                              $$f{group} 
    ~~                ^<<<<<<<<<<<<<<<<<<<<<<<<
                       $$f{item}
    .
    write ;
    }
    

    对于所有回答我问题的人,非常感谢您的帮助,非常感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-03
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多