JohnnyP JohnnyP - 6 months ago 17
Perl Question

Find-Replace Multiple Occurrences of a string and append iterating number

How can I iterate over the code of an html file and find certain recurring text and then append a word and and iterating number to it.

So:
<!-- TemplateBeginEditable -->
<!-- TemplateBeginEditable -->
<!-- TemplateBeginEditable -->
etc...

Becomes :
<!-- TemplateBeginEditable Event=1 -->
<!-- TemplateBeginEditable Event=2 -->
<!-- TemplateBeginEditable Event=3 -->
etc...


I have tried PERL thinking it would be the easiest/fastest and went to jQuery and then back to PERL.

It seems simple enough to find/replace many ways with REGEX and return an array of the occurrences, but getting the iterating variable tacked on proves to be more of a challenge.

Latest Example of what I have tried:

#!/usr/bin/perl -w

# Open input file
open INPUTFILE, "<", $ARGV[0] or die $!;
# Open output file in write mode
open OUTPUTFILE, ">", $ARGV[1] or die $!;

# Read the input file line by line
while (<INPUTFILE>) {
my @matches = ($_ =~ m/TemplateBeginEditable/g);
### what do I do ith matches array? ###
$_ =~ s/TemplateBeginEditable/TemplateBeginEditable Event=/g;
print OUTPUTFILE $_;

}


close INPUTFILE;
close OUTPUTFILE;

Answer

To perform a replacement, you don't need to match the pattern before, you can directly perform the replacement. Example with your code:

while (<INPUTFILE>) {
    s/TemplateBeginEditable/TemplateBeginEditable Event=/g;
    print OUTPUTFILE $_; 
}

Now to add a counter incremented at each replacement, you can put a piece of code in the pattern itself using this syntax:

my $i;

while (<INPUTFILE>) {
    s/TemplateBeginEditable(?{ ++$i })/TemplateBeginEditable Event=$i/g;
    print OUTPUTFILE $_; 
}

To make it shorter you can use the \K feature to change the start of the match result:

while (<INPUTFILE>) {
    s/TemplateBeginEditable\K(?{ ++$i })/ Event=$i/g;
    print OUTPUTFILE $_; 
}

Or with a one-liner:

perl -pe 's/TemplateBeginEditable\K(?{++$i})/ Event=$i/g' file > output