地图与拆分&修剪Perl

时间:2010-07-02 02:42:14

标签: perl map split trim

如何使用带分割功能的地图来修剪成分:$ a,$ b,$ c和$ d; $ line?

my ($a, $b, $c, $d, $e) = split(/\t/, $line);

# Perl trim function to remove whitespace from the start and end of the string
sub trim($)
{
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

6 个答案:

答案 0 :(得分:4)

除非你需要,否则不要在你的函数上使用原型($)

my ( $a, $b, $c, $d, $e ) =
  map {s/^\s+|\s+$//g; $_}    ## Notice the `, $_` this is common
  , split(/\t/, $line, 5)
;

请勿忘记上面s///返回的替换计数 - 不是$_。所以,我们明确地这样做了。

或更简单:

my @values = map {s/^\s+|\s+$//g; $_}, split(/\t/, $line, 5), $line

答案 1 :(得分:3)

map需要两个输入:

  • 表达式或块:这将是trim表达式(您不必编写自己的表达式 - 它在CPAN上)
  • 以及要操作的列表:这应该是split的输出:
use String::Util 'trim';
my @values = map { trim($_) } split /\t/, $line;

答案 2 :(得分:2)

这应该有效:

my ($a, $b, $c, $d, $e) = map {trim ($_)} (split(/\t/, $line));

顺便说一下,这是一个小问题,但你不应该使用$ a和$ b作为变量名。

答案 3 :(得分:1)

你也可以在这里使用“foreach”。

foreach my $i ($a, $b, $c, $d, $e) {
  $i=trim($i);
}

答案 4 :(得分:0)

只是为了变化:

my @trimmed = grep { s/^\s*|\s*$//g } split /\t/, $line;

grep充当列表的过滤器。这就是为什么\s+需要在正则表达式中更改为\s* s的原因。在0或更多空格上强制匹配会阻止grep过滤掉列表中没有前导或尾随空格的项目。

答案 5 :(得分:0)

当我修剪弦乐时,我不经常想保留原作。拥有一个sub的抽象会很好,但也不必对临时值大惊小怪。

事实证明,我们可以做到这一点,正如perlsub所解释的那样:

  

传入的任何参数都显示在数组@_中。因此,如果您使用两个参数调用函数,那么这些参数将存储在$_[0]$_[1]中。数组@_是一个本地数组,但其元素是实际标量参数的别名。特别是,如果更新元素$_[0],则更新相应的参数(如果不可更新,则会发生错误)。

在您的情况下,trim变为

sub trim {
  for (@_) {
    s/^ \s+  //x;
    s/  \s+ $//x;
  }
  wantarray ? @_ : $_[0];
}

请注意,mapfor是堂兄弟,所以使用trim中的循环,您不再需要map。例如

my $line = "1\t 2\t3 \t 4 \t  5  \n";    
my ($a, $b, $c, $d, $e) = split(/\t/, $line);    

print "BEFORE: [", join("] [" => $a, $b, $c, $d), "]\n";
trim $a, $b, $c, $d;
print "AFTER:  [", join("] [" => $a, $b, $c, $d), "]\n";

输出:

BEFORE: [1] [ 2] [3 ] [ 4 ]
AFTER:  [1] [2] [3] [4]