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

前端 未结 5 1780
花落未央
花落未央 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:30

    See perldoc perlvar:

    use strict; use warnings;
    
    use Test::More tests => 5;
    
    my %src = (
        q{'I want to' 'extract the word' 'PERL','from this string'}
        => q{'I want to' 'extract the word' 'Perl','from this string'},
        q{'What about', 'getting','PERL','from','here','?'}
        => q{'What about', 'getting','Perl','from','here','?'},
        q{'How can I','use' 'PERL','to process this' 'line'}
        => q{'How can I','use' 'Perl','to process this' 'line'},
        q{Invalid} => q{Invalid},
        q{'Another invalid string'} => q{'Another invalid string'}
    );
    
    while ( my ($src, $target) = each %src ) {
        ok($target eq subst_n($src, 3, 'Perl'), $src)
    }
    
    sub subst_n {
        my ($src, $index, $replacement) = @_;
        return $src unless $index > 0;
        while ( $src =~ /'.*?'/g ) {
            -- $index or return join(q{'},
                substr($src, 0, $-[0]),
                $replacement,
                substr($src, $+[0])
            );
        }
        return $src;
    }
    

    Output:

    C:\Temp> pw
    1..5
    ok 1 - 'Another invalid string'
    ok 2 - 'How can I','use' 'PERL','to process this' 'line'
    ok 3 - Invalid
    ok 4 - 'What about', 'getting','PERL','from','here','?'
    ok 5 - 'I want to' 'extract the word' 'PERL','from this string'

    Of course, you need to decide what happens if an invalid $index is passed or if the required match is not found. I just return the original string in the code above.

提交回复
热议问题