如何使用条件运算符在 perl 映射操作中放置正则表达式

How to place a regular expression in a perl map operation using the conditional operator

您好,我尝试使用映射操作和带正则表达式的条件运算符来缩短循环构造,但没有得到正确的结果。我认为失败的原因是分配和正则表达式运算符之间的差异(==~ )。这种方法的正确表述是什么。

长版:

print("TABLE.BEGIN\n");
while(my @data = $sth->fetchrow_array) {
   $row++;
   for my $ix (0..$#data) {
       my $val = $data[$ix];
       if ($val) {
           $val =~ s/\t/[:TAB:]/g;
       } else {
           $val = 'NULL';
       }
       $data[$ix] = $val;
   }
   print "ROW: $row\t",join("\t",@data),"\n";
}
print("END.TABLE\n");

长版结果

TABLE.BEGIN
ROW: 1  12  79  1   PhoViComp   2017-05-22-PhoViComp    2017-05-22  32632   rostock HRO punjabi 2017-05-22-PhoViComp    /net/server/path/
END.TABLE

短版

print("TABLE.BEGIN\n");
my $row=0;
while(my @data = $sth->fetchrow_array) {
    $row++;
    @data = map { $_ ? s/\t/[:TAB:]/g : 'NULL' } @data;
    print "ROW: $row\t",join("\t",@data),"\n";
}
print("END.TABLE\n");

短版结果

TABLE.BEGIN
ROW: 1                                              
END.TABLE

在列表上下文中,s/\t/[:TAB:]/g returns 1,除此之外别无其他。您需要 return 修改后的 $_.


所以你有接近

的东西
for (@data) {
    my $val = $_;
    if (defined($val)) {
        $val =~ s/\t/[:TAB:]/g;
    } else {
        $val = 'NULL';
    }

    $_ = $val;
}

map 版本为

@data = map {
    my $val = $_;
    if (defined($val)) {
        $val =~ s/\t/[:TAB:]/g;
    } else {
        $val = 'NULL';
    }

    $val
} @data;

当然,你可以这样写

$_ = defined($_) ? s/\t/[:TAB:]/rg : 'NULL' for @data;            # 5.14+

等效(但较慢)map 版本为

@data = map { defined($_) ? s/\t/[:TAB:]/rg : 'NULL' } @data;     # 5.14+