我将这个短子程序写入左,中,右对齐多行字符串。
我怎样才能让它变得更好? (更短,更漂亮,优化)?你能提出一些建议吗?
#!/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的初学者,我确信我错过了那种让我的代码变得神奇的天才。
一些建议?
答案 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;
}