How can I pad part of a string with spaces, in Perl?

匿名 (未验证) 提交于 2019-12-03 08:35:02

问题:

Which version would you prefer?

#!/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; 

Option 1:

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

Option 2:

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

say "$key$value"

回答1:

I don't like option 2 as it introduces an unnecessary special case.

I would refactor out the construction of the prompt suffix:

    # Possible at top of program     my $suffix =  ( ' ' x $p ) . $prompt;      # Later...      $key .= $suffix ;


回答2:

I would prefer

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

or

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

instead of all this weird stuff.

From sprintf documentation:

The flag characters

'-' The converted value is to be left adjusted on the field boundary. (The default is right justification.) The converted value is padded on the right with blanks, rather than on the left with blanks or zeros. A '-' overrides a 0 if both are given.

The field width

An optional decimal digit string (with nonzero first digit) specifying a minimum field width. If the converted value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the left-adjustment flag has been given). Instead of a decimal digit string one may write '*' or '*m$' (for some decimal integer m) to specify that the field width is given in the next argument, or in the m-th argument, respectively, which must be of type int. A negative field width is taken as a '-' flag followed by a positive field width. In no case does a nonexistent or small field width cause truncation of a field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result.



回答3:

Call me old-school, but I'd use printf() or sprintf():

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

That left justifies the string $key into 33 spaces, adds $prompt and $value and a newline. If I wanted to calculate the length for the first part dynamically:

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

Since it is one line instead of the question's 4 (option 1) or 6 (option 2), it scores favourably on the succinctness scale.



回答4:

I looks a little weird, but this works (until now):

#!/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 );


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!