Substituindo várias strings em um arquivo de uma só vez

1

Suponha que eu queira substituir todos os AAA por BBB e todos os BBB por AAA em um arquivo de texto.

A coisa que parece uma solução óbvia (em Perl ou em Sed) é:

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

Mas isso não funciona porque pode substituir o AAA por BBB e substituí-lo por AAA.

Quais soluções para esse problema existem?

Talvez você possa fornecer algum código Perl (ou Python ou qualquer outro)?

    
por porton 22.12.2014 / 17:16

2 respostas

1

Ah, eu encontrei um módulo que faz isso:

perl -MReplaceMultiple -e 'print replace_multiple({"AAA"=>"BBB", "BBB"=>"AAA"}, "AAABBB"), "\n";'

ReplaceMultiple.pm:

package ReplaceMultiple;

use strict;
use warnings;

our (@ISA, @EXPORT);
require Exporter; @ISA = qw(Exporter);
@EXPORT = qw(replace_multiple_inplace replace_multiple);

sub replace_multiple_inplace {
  my ($hash, $str_ref) = @_;
  my $obj = ReplaceMultiple->new($hash);
  return $obj->apply_inplace($str_ref);
}

sub replace_multiple {
  my ($hash, $str) = @_;
  my $obj = ReplaceMultiple->new($hash);
  return $obj->apply($str);
}

sub new {
  my ($class, $hash) = @_;
  my $re_str = "(" . (join '|', map { "\Q$_\E" } keys %$hash) . ")";
  my $self = bless {HASH=>$hash, RE=>qr/$re_str/}, $class;
  return $self;
}

sub apply_inplace {
  my ($self, $str_ref) = @_;
  $$str_ref =~ s/$self->{RE}/$self->{HASH}{$1}/g;
  return $$str_ref;
}

sub apply {
  my ($self, $str) = @_;
  my $str2 = $str;
  return $self->apply_inplace(\$str2);
}

1;
    
por 22.12.2014 / 17:28
2

Em Perl, você pode usar o sinalizador /e para e na substituição de uma substituição:

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

Explicação:

  • (AAA|BBB) corresponde a AAA ou BBB e salva a string correspondente em $ 1.
  • condition ? true : false é o "operador ternário". Ele retorna o valor "true" se a "condição" for verdadeira, o "falso" caso contrário. Então, nesse caso, ele retorna a string a ser usada para substituição.
  • /ge significa "globalmente", isto é, não apenas uma vez por linha, e "eval", isto é, entende a peça de substituição como código a ser executado.
por 22.12.2014 / 17:33