一次替换文件中的多个字符串

一次替换文件中的多个字符串

假设我想在文本文件中将所有 AAA 替换为 BBB,将所有 BBB 替换为 AAA。

看起来明显的解决方案(在 Perl 或 Sed 中)是:

s/AAA/BBB/g;s/BBB/AAA/g;

但这不起作用,因为在用 BBB 替换 AAA 后,还可以将其替换回 AAA。

有哪些解决方案可以解决这一问题?

也许您可以提供一些 Perl(或 Python 或其他)代码?

答案1

哦,我发现了一个可以做到这一点的模块:

perl -MReplaceMultiple -e ‘打印 replace_multiple({“AAA”=>“BBB”, “BBB”=>“AAA”}, “AAABBB”), “\n”;’

ReplaceMultiple.pm:

包ReplaceMultiple;

使用严格;
使用警告;

我们的(@ISA,@EXPORT);
需要出口商;@ISA = qw(出口商);
@EXPORT = qw(replace_multiple_inplace 替换多个);

子替换_多个_就地{
  我的($hash,$str_ref)= @_;
  我的 $obj = ReplaceMultiple->new($hash);
  返回 $obj->apply_inplace($str_ref);
}

子替换多个{
  我的($hash,$str)= @_;
  我的 $obj = ReplaceMultiple->new($hash);
  返回 $obj->apply($str);
}

子新{
  我的($class,$hash)= @_;
  我的 $re_str = "(" . (join '|', map { "\Q$_\E" } keys %$hash) . ")";
  我的 $self = 祝福 {HASH=>$hash, RE=>qr/$re_str/}, $class;
  返回$self;
}

子应用_就地{
  我的($self,$str_ref)=@_;
  $$str_ref =~ s/$self->{RE}/$self->{HASH}{$1}/g;
  返回 $$str_ref;
}

子应用{
  我的($self,$str)=@_;
  我的 $str2 = $str;
  返回 $self->apply_inplace(\$str2);
}

1;

答案2

在 Perl 中,你可以使用标志/e在替换的替换部分中评估代码:

s/(AAA|BBB)/'AAA' eq $1 ? 'BBB' : AAA/ge

解释:

  • (AAA|BBB)匹配 AAA 或 BBB 并将匹配的字符串保存在 $1 中。
  • condition ? true : false是“三元运算符”。如果“条件”为真,则返回“真”值,否则返回“假”。因此,在本例中,它返回用于替换的字符串。
  • /ge意思是“全局”,即每行不只一次,以及“eval”,即将替换部分理解为要运行的代码。

相关内容