4

如何使用带有 split 功能的 map 来修剪成分:$a、$b、$c 和 $d;$线?

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;
}
4

6 回答 6

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
于 2010-07-02T03:09:21.413 回答
3

map接受两个输入:

  • 表达式或块:这将是修剪表达式(您不必编写自己的 - 它在 CPAN 上)
  • 和一个要操作的列表:这应该是split' 输出:
use String::Util 'trim';
my @values = map { trim($_) } split /\t/, $line;
于 2010-07-02T02:50:30.730 回答
2

这应该有效:

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

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

于 2010-07-02T02:44:34.497 回答
1

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

foreach my $i ($a, $b, $c, $d, $e) {
  $i=trim($i);
}
于 2010-07-02T08:10:04.243 回答
0

只为多样化:

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

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

于 2010-07-02T07:17:26.867 回答
0

当我修剪字符串时,我通常不想保留原件。拥有 sub 的抽象但也不必对临时值大惊小怪。

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

传入的任何参数都显示在数组中@_。因此,如果您调用带有两个参数的函数,它们将存储在$_[0]and中$_[1]。该数组@_是一个本地数组,但它的元素是实际标量参数的别名。特别是,如果一个元素$_[0]被更新,相应的参数也会被更新(或者如果它不可更新,则会发生错误)。

在你的情况下,trim变成

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

记住mapandfor是堂兄弟,所以有了循环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";

输出:

之前:[1] [2] [3] [4]
之后:[1] [2] [3] [4]
于 2010-07-02T14:52:02.867 回答