Perl对齐文本(左,中,右)没有包

时间:2014-08-23 09:17:50

标签: regex perl alignment

我将这个短子程序写入左,中,右对齐多行字符串。

我怎样才能让它变得更好? (更短,更漂亮,优化)?你能提出一些建议吗?

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

# A bit of text
$_ = <<END;
     Lorem ipsum dolor sit amet consectetur adipiscing elit
          Curabitur pretium odio dictum nisl posuere, vitae mollis nibh facilisis
   Curabitur tempus tincidunt ante eget facilisis
     Pellentesque ut accumsan dui, nec semper odio
        Ut libero lacus, fermentum quis ultricies quis, tempus nec augue
                   Mauris tincidunt hendrerit accumsan
END

# Test each alignment case
for my $align ('left', 'center', 'right') {
    print align($_, $align)."\n";
}

# Alignment subroutine
sub align {
    my ($_, $align) = @_;    # Text to align, Alignment type
    my $re = qw/^([^\n]*)$/; # A regex to match each line
    s/^[ \t]+|[ \t]+$//gm;   # Remove trailing/leading spaces

    # Get longest line
    my $max = 0;
    $max = length($1) > $max ? length($1) : $max while /$re/gm;

    # Do the alignment
    s|$re|$1 . " " x ($max-length($1))|mge if $align eq 'left';
    s|$re|" " x (($max-length($1))/2) . $1|mge if $align eq 'center';
    s|$re|" " x ($max-length($1)) . $1|mge if $align eq 'right';

    return $_;
}

我是Perl的初学者,我确信我错过了那种让我的代码变得神奇的天才。

一些建议?

2 个答案:

答案 0 :(得分:4)

一些小修改;使用$_作为词法(my)变量,更简单$re并正确编译(qr vs qw)时,更新的perl会发出警告,删除不需要的三元赋值,添加{{1跳过某些条件。

elsif

试图使用anon hashref而不是sub align { local $_ = shift; my ($align) = @_; # Text to align, Alignment type my $re = qr/^(.*)/m; s/^\h+|\h+$//gm; # Remove trailing/leading spaces # Get longest line my $max = 0; length($1) > $max and $max = length($1) while /$re/g; if ($align eq 'left') { s|$re|$1 . " " x ($max-length($1))|ge } elsif ($align eq 'center') { s|$re|" " x (($max-length($1))/2) . $1|ge } elsif ($align eq 'right') { s|$re|" " x ($max-length($1)) . $1|ge } return $_; } ,但这不会有助于提高可读性,

elsif

答案 1 :(得分:2)

我认为最明显的是将字符串拆分成行并在循环中处理它们。

喜欢这个

#!/usr/bin/env perl

use strict;
use warnings;
use 5.010;

sub max;

my $text = <<END_TEXT;
   Lorem ipsum dolor sit amet consectetur adipiscing elit
        Curabitur pretium odio dictum nisl posuere, vitae mollis nibh facilisis
 Curabitur tempus tincidunt ante eget facilisis
   Pellentesque ut accumsan dui, nec semper odio
      Ut libero lacus, fermentum quis ultricies quis, tempus nec augue
                 Mauris tincidunt hendrerit accumsan
END_TEXT

for my $align (qw/ left right centre /) {
  print align($text, $align), "\n";
}

sub align {

   state %core;
   @core{qw/ left centre center right /} = (0, 1, 1, 2) unless %core;

   my @lines = split m{$/}, shift;
   s/\A\s+|\s+\z//g for @lines;

   my @indices = (1, 2);
   splice @indices, $core{lc shift}, 0, 0;

   my $max = max map length, @lines;

   return join '', map {

      my $padlen = $max - length;
      my $pad1   = ' ' x $padlen;
      my $pad2   = substr($pad1, 0, $padlen/2, '');

      join '', ($_, $pad1, $pad2)[@indices], "\n";

   } @lines;
}


sub max {
  my $max = shift;
  $_ > $max and $max = $_ for @_;
  $max;
}