How can I substitute the nth occurrence of a match in a Perl regex?

前端 未结 5 1781
花落未央
花落未央 2020-12-19 16:24

Following up from an earlier question on extracting the n\'th regex match, I now need to substitute the match, if found.

I thought that I could define the extraction

5条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-19 17:07

    Reworking an answer to an earlier question, match n-1 times and then replace the next. Memoizing patterns spares poor Perl having to recompile the same patterns over and over.

    my $_quoted = qr/'[^']+'/; # ' fix Stack Overflow highlighting
    my %_cache;
    sub replace_nth_quoted { 
      my($string,$index,$replace) = @_;
      my $pat = $_cache{$index} ||=
        qr/ ^
            (                    # $1
              (?:.*?$_quoted.*?) # match quoted substrings...
                {@{[$index-1]}}  # $index-1 times
            )
            $_quoted             # the ${index}th match
          /x;
    
      $string =~ s/$pat/$1$replace/;
      $string;
    }
    

    For example

    my $string = "'How can I','use' 'PERL','to process this' 'line'";
    print replace_nth_quoted($string, 3, "'Perl'"), "\n";
    

    outputs

    'How can I','use' 'Perl','to process this' 'line'

提交回复
热议问题