Perl replace multiple strings simultaneously

后端 未结 2 1906
夕颜
夕颜 2020-12-17 17:23

Is there any way to replace multiple strings in a string? For example, I have the string hello world what a lovely day and I want to replace what a

2条回答
  •  温柔的废话
    2020-12-17 18:06

    Well, mainly it's not working as tr///d has nothing to do with your request (tr/abc/12/d replaces a with 1, b with 2, and removes c). Also, by default arrays don't interpolate into regular expressions in a way that's useful for your task. Also, without something like a hash lookup or a subroutine call or other logic, you can't make decisions in the right-hand side of a s/// operation.

    To answer the question in the title, you can perform multiple replaces simultaneously--er, in convenient succession--in this manner:

    #! /usr/bin/env perl
    use common::sense;
    
    my $sentence = "hello world what a lovely day";
    
    for ($sentence) {
      s/what/it's/;
      s/lovely/bad/
    }
    
    say $sentence;
    

    To do something more like what you attempt here:

    #! /usr/bin/env perl
    use common::sense;
    
    my $sentence = "hello world what a lovely day";
    
    my %replace = (
      what => "it's",
      lovely => 'bad'
    );
    
    $sentence =~ s/(@{[join '|', map { quotemeta($_) } keys %replace]})/$replace{$1}/g;
    
    say $sentence;
    

    If you'll be doing a lot of such replacements, 'compile' the regex first:

    my $matchkey = qr/@{[join '|', map { quotemeta($_) } keys %replace]}/;
    
    ...
    
    $sentence =~ s/($matchkey)/$replace{$1}/g;
    

    EDIT:

    And to expand on my remark about array interpolation, you can change $":

    local $" = '|';
    $sentence =~ s/(@{[keys %replace]})/$replace{$1}/g;
    # --> $sentence =~ s/(what|lovely)/$replace{$1}/g;
    

    Which doesn't improve things here, really, although it may if you already had the keys in an array:

    local $" = '|';
    $sentence =~ s/(@keys)/$replace{$1}/g;
    

提交回复
热议问题