Perl:测试正则表达式而不创建新变量

时间:2018-05-11 13:06:13

标签: perl

很抱歉,如果这是一个基本问题,但我对perl有点新鲜,我觉得应该有办法做到这一点,但我找不到任何文档。我想知道你是否可以在没有抛弃变量$doto的情况下执行以下操作:

my $file="foo/bar.c";
my $doto = $file;
$doto =~ s/\.c$/\.o/;
print ".o exists" if ( -f $doto );

就是这样:

print ".o exists" if ( -f ($file =~ s/\.c$/\.o/gr) );

(但是当然会产生编译错误)。

我的编译错误如下:

  

Bareword发现运营商预计在第2行,接近" s / .c $ /。o / gr"

这是perl, v5.8.9

3 个答案:

答案 0 :(得分:4)

您的陈述

$aglutinatedRows = [];
$lastRowId = $rowwwithdiffer[0];
$firstRowInSequence = $rowwwithdiffer[0];

foreach(array_slice($rowwwithdiffer, 1) as $row) {
    if ($row == $lastRowId + 1) {
        $lastRowId = $row;
    } else {
        $aglutinatedRows[] = $firstRowInSequence != $lastRowId ? $firstRowInSequence . ' - ' . $lastRowId : lastRowId;
        $firstRowInSequence = $row;
        $lastRowId = $row;
    }
}

适用于支持print ".o exists" if ( -f ($file =~ s/\.c$/\.o/gr) ) 修饰符-v5.14或更高版本的Perl版本。 (请注意/r是多余的。)

没有它就没有办法在不修改变量的情况下应用替换,尽管你可以使用块来使它成为一个非常短暂的临时变量

/g

答案 1 :(得分:2)

这个答案谈到了使实际的print if -f查找代码更具可读性。如果您希望代码运行得更快,那么此解决方案比您的丑陋更昂贵。

因为在您的Perl版本中没有非破坏性替换,所以您可以为此实现自己的功能。它不会像s///r那样好,但它能完成这项工作。如果您已经多次出现过这种类型的代码,那么这将是有意义的。

sub replace {
    my ($text, $pattern, $replacement) = @_;

    $text =~ s{$pattern}{$replacement}g; # do you need /g?
    return $text;
}

# ... later

print ".o exists" if -f replace($file, qr/\.c$/, '.o');

这已经为你制作副本,就像你的临时变量那样,所以$file实际上不会被改变。

请注意,您的/g无用,因为文件名只会包含该行的一端,但以后可能没用。但是,最好不要在那里修复它,而是将可选标志作为另一个参数传递。

replace( $file, qr/.../, '.o', 'g' ); # where 'g' just means any true value

sub replace {
    my ($text, $pattern, $replacement, $global) = @_;

    if ($global) {
         $text =~ s{$pattern}{$replacement}g;
    } else {
         $text =~ s{$pattern}{$replacement};
    }

    return $text;
}

您通常也不需要逃避替换部分中的.,因为它实际上不是正则表达式模式,只是一个字符串。

答案 2 :(得分:2)

我会通过添加如下函数来接近它。

sub doto_exists {
    my $doto = shift;
    $doto =~ s/\.c$/\.o/;
    return (-f $doto);
}

$file = "file1.c";

print ".o exists\n" if doto_exists($file) ;