Perl 一次搜索和替换多个字符串

时间:2021-04-01 20:06:30

标签: perl

我有以下 Perl 代码,它可以正常工作,没有任何错误。我想知道是否有可能一次在 foreach 循环中进行四个替换并删除与第五个替换匹配的整行。 我不明白到目前为止我所经历的建议解决方案,我试图避免使用哈希。 我将不胜感激。

#!/usr/bin/perl -w
use strict;
use warnings;
                                                                            
my @data=<DATA>;
foreach $lines (@data){
$lines =~ s/\//9/g;
$lines =~ s/333/33300/g;
$lines =~ s/555/55500/g;
$lines =~ s/=|==//g;
$lines =~ s/NIL|N I L//g;       # preferably delete this whole line
}

print "@lines\n";
exit 0;


__DATA__
63740 32575 40606 10217 20159 48528 83230 333 20/// 59008 83820=
63820 32580 20803 10305 20225 40130 82200 333 20262 59009 82823==
63135 NIL=
63742 12570 10507 10208 20148 48509 60014 81100 333 20155 59012 81820=

1 个答案:

答案 0 :(得分:2)

my %map = (
   '/'   => '9',
   '333' => '33300',
   '555' => '55500',
   '='   => '',
);

my $pat = join '|', map quotemeta, keys(%map);
my $re = qr/($pat)/;

while (<>) {
   next if /NIL/;
   s/$re/$map{$1}/g;
   print;
}

上面的工作是因为匹配的字符串是翻译映射的键。但您想添加以下内容:

s/^.*NIL.*\z//

没有简单的方法可以通用地处理这种情况。但我们可以专门处理这种情况。

my %map = (
   '/'   => '9',
   '333' => '33300',
   '555' => '55500',
   '='   => '',
);

my $pat = join '|', map quotemeta, keys(%map);
my $re = qr/^.*NIL.*\z|($pat)/;

while (<>) {
   s/$re/ defined($1) ? $map{$1} : "" /eg;
   print;
}

这更难看,但可能更快。将整个文件加载到内存中会更快。

my %map = (
   '/'   => '9',
   '333' => '33300',
   '555' => '55500',
   '='   => '',
   '=='  => '',
);

my $pat = join '|', map quotemeta, keys(%map);
my $re = qr/^.*NIL.*\n?|($pat)/m;

local $/;
while (<>) {
   s/$re/ defined($1) ? $map{$1} : "" /eg;
   print;
}
相关问题