2009-06-15 108 views
3

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

目前我有:

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

我不知道如果SUBSTR置换将有助于为“模式”可以是“AB”或“CD”或“EF”或“GH”等

谢谢! 默认碧

+0

你能举一个例子,看看前后的样子吗? – YGA 2009-06-15 20:27:33

+1

输出示例: BEFORE 均值:100 AFTER 方差:100 或 前 通道数据:50 AFTER 频道频率:50个 谢谢! – 2009-06-15 20:31:51

回答

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是有点生疏,所以语法可能不准确。

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

0
while (<IN>) 
{ 
    s/^pattern:/myPattern:/; 
    print OUT 
} 
+0

无论它是否与第一个模式匹配,都会打印每一行。当我读到原始问题时,只有匹配的行应该转换并写入OUT – 2009-06-15 20:37:23

1

Perl的替换操作(一)使用的第一场比赛,(b)只更换一个匹配和(c)如果进行了替换和虚假的,如果不是,则返回true。

所以:

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

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

+0

请注意,您将剥离第一个冒号以及此替换。 – 2009-06-16 19:44:03

0

这可能是你想要什么:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)"; 
while (<IN>) 
{ 
    if (/$expr:/) 
    { 
     s/$expr/$myPattern/; 
     print FILE; 
    } 
} 
0

上面要求做的最简单的方法是重新使用您的代码,但包含替换。

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

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

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。