3

我正在读取输入文件 (IN) 的每一行并将读取的行打印到输出文件 (OUT) 如果该行以其中一种模式开头,例如“ab”、“cd”、“ef”、“gh” ”ij”等。打印的行格式为“pattern: 100”或格式“pattern: 100:200”。我需要将“pattern”替换为“myPattern”,即将当前行打印到FILE,但将第一次出现“:”之前的所有文本替换为“myPattern”。做这个的最好方式是什么?

目前我有:

while ( <IN> )
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/;
}

我不确定 substr 替换是否会有所帮助,因为“模式”可以是“ab”或“cd”或“ef”或“gh”等。

谢谢!双

4

6 回答 6

3

一般来说,这样做:

my %subst = ( 'ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy' );
my $regex = join( '|', map quotemeta, sort { length($b) <=> length($a) } keys %subst );
$regex = qr/^($regex):/;

while ( <IN> ) {
    print FILE if s/$regex/$subst{$1}:/;
}

该排序将最长的放在首位,因此如果数据具有 ab:: 并且 ab 和 ab: 都被替换,则使用 ab: 代替 ab。

于 2009-06-15T23:29:34.860 回答
1

Perl 的替换运算符默认情况下 (a) 使用第一个匹配项,(b) 只替换一个匹配项, (c) 如果进行了替换,则返回 true,否则返回 false。

所以:

while ( <IN> )
{ 
    if (s/<pattern1>:/<replace1>/ ||
        s/<pattern2>:/<replace2>/) {
       print FILE;
    }
}

应该为你工作。请注意,由于短路,只会进行一次替换。

于 2009-06-15T20:35:26.060 回答
0
while ( <IN> )
{ 
  s/^pattern:/myPattern:/;
  print OUT
}
于 2009-06-15T20:35:02.957 回答
0

这可能是你想要的:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)";
while (<IN>)
{
    if (/$expr:/)
    {
        s/$expr/$myPattern/;
        print FILE;
    }
}
于 2009-06-15T20:35:31.487 回答
0
sub replacer {

    $line = shift;
    $find = shift;
    $replace = shift;

    $line =~ /([^:]+):/
    if ($1 =~ /$find/) { 
         $line =~ s/([^:]+):/$replace/ ;
         return $line;      
    }
    return ;

}

while (<IN>)
{
    print OUT replacer ($_,"mean","variance");
    print OUT replacer ($_,"pattern","newPattern");
}

我的 perl 有点生疏,所以语法可能不准确。

编辑:把它放在一个函数中。

于 2009-06-15T20:37:49.500 回答
0

完成上述要求的最短方法是重用您的代码,但包括替换。

while ( <IN> )
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/;
}

任何左侧模式都将被替换。如果左侧不匹配,则不会打印任何内容。

于 2009-06-15T20:53:45.890 回答