代码之家  ›  专栏  ›  技术社区  ›  Stephen Jennings

如何在Perl中用空格填充字符串的一部分?

  •  12
  • Stephen Jennings  · 技术社区  · 6 年前

    您喜欢哪个版本?

    #!/usr/bin/env perl
    use warnings; 
    use strict;
    use 5.010;
    
    my $p = 7; # 33
    my $prompt = ' : ';
    my $key = 'very important text';
    my $value = 'Hello, World!';
    
    my $length = length $key . $prompt;
    $p -= $length; 
    

    选项1:

    $key = $key . ' ' x $p . $prompt;
    

    选项2:

    if ( $p > 0 ) { 
        $key = $key . ' ' x $p . $prompt;
    }
    else {
        $key = $key . $prompt;
    }
    

    say "$key$value"
    
    4 回复  |  直到 8 年前
        1
  •  8
  •   justintime    8 年前

    我不喜欢选项2,因为它引入了不必要的特殊情况。

    我将重构提示后缀的构造:

        # Possible at top of program
        my $suffix =  ( ' ' x $p ) . $prompt;
    
        # Later...
    
        $key .= $suffix ;
    
        2
  •  29
  •   Hynek -Pichi- Vychodil    8 年前

    我宁愿

    sprintf "%-7s : %s", $key, $value;
    

    sprintf "%-*s : %s", $p, $key, $value;
    

    而不是所有这些奇怪的东西。

    sprintf 文档:

    标志字符

    '-' 转换值将在场边界上进行左调整。(默认为右对齐。)转换后的值用空格填充在右侧,而不是用空格或零填充在左侧。一 “-” 覆盖 0 如果两者都给出。

    视场宽度

    指定最小字段宽度的可选十进制数字字符串(第一个数字不为零)。如果转换后的值的字符数少于字段宽度,则将在其左侧填充空格(如果给定了左调整标志,则为右)。可以写的不是十进制数字字符串 '*' '*m$' (对于某些十进制整数 m )指定字段宽度分别在下一个参数或m-th参数中给定,该参数的类型必须为int。负字段宽度被视为 “-” 标志,后跟一个正字段宽度。在任何情况下,不存在或较小的字段宽度都不会导致字段截断;如果转换的结果大于字段宽度,则该字段将展开以包含转换结果。

        3
  •  5
  •   Jonathan Leffler    15 年前

    叫我老派,但我会用printf()或sprintf():

    printf "%-33s%s%s\n", $key, $prompt, $value;
    

    将字符串$key左对齐到33个空格中,添加$prompt和$value以及新行。如果我想动态计算第一部分的长度:

    printf "%-*s%s%s\n", $len, $key, $prompt, $value;
    

    因为它是一行而不是问题的4(选项1)或6(选项2),所以它在简洁程度上得分很好。

        4
  •  1
  •   Stephen Jennings    8 年前

    我看起来有点奇怪,但这个方法(直到现在)仍然有效:

    #!/usr/bin/env perl
    use warnings; use strict;
    use 5.010;
    use utf8;
    use Term::Size;
    my $columns = ( Term::Size::chars *STDOUT{IO} )[0];
    binmode STDOUT, ':encoding(UTF-8)';
    use Text::Wrap;
    use Term::ANSIColor;
    
    sub my_print {
        my( $key, $value, $prompt, $color, $p ) = @_;
        my $length = length $key.$prompt;
        $p -= $length;
        my $suff = ( ' ' x $p ) . $prompt;
        $key .=  $suff;
        $length = length $key;
        my $col = $columns - $length;
        $Text::Wrap::columns = $col;
        my @array = split /\n/, wrap ( '','', $value ) ;
        $array[0] = colored( $key, $color ) . $array[0];
        for my $idx ( 1..$#array ) {
        $array[$idx] = ( ' ' x $length ) . $array[$idx];
        }
        say for @array;
    }
    
    my $prompt = ' : ';
    my $color = 'magenta';
    my $p = 30;
    my $key = 'very important text';
    my $value = 'text ' x 40;
    
    my_print( $key, $value, $prompt, $color, $p );