perl - 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=
解决方案
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;
}
推荐阅读
- r - 如何使用 timevis 更改时间线可视化中点的颜色?
- php - 为什么,我收到带有注释 $start var 的致命错误?
- java - 如何从spring控制器重定向到本地页面?
- clojurescript - 单击提交时从表单中获取值
- django - 如何将现有表单中的已删除内容显示到完全独立的 url,它在 django 中显示已删除项目的位置
- android - 如何将数据从本机应用程序传递到颤振?
- c++ - 为什么 std::ofstream 会在没有 std::ios_base::trunc 的情况下截断?
- rust - 制作切片时,所有权和借款如何运作?
- ios - 视频没有在 AVPlayer 中播放
- javascript - 单击 svg 元素时添加下拉菜单