Home > Enterprise >  Perl: Repeat a pattern x times, where x is a match of \d
Perl: Repeat a pattern x times, where x is a match of \d

Time:11-16

I have matched a certain pattern and additionally a number via

perl -pe 's/\(pattern\)(\d)/ ... /'

I know that I can access the pattern by putting $1 where the ... are and the number by using $2. How can I now repeat pattern $2 times where the ... are? To be more specific, I have an expression like:

perl -pe 'while(s/Power\(((?:(?!Power\().) ?),2\)/(($1)*($1))/){}' file.txt

And I want to generalize this to not only match the 2, which is hardcoded in there to repeat $1 twice, but to match any number n and repeat $1 n times. All of this should still be done in a oneliner.

So for example calling the script onto expressions like

Power(Power(x,3),2)

should return

(((x)*(x)*(x))*((x)*(x)*(x)))

CodePudding user response:

You can use

perl -pe 'while(s/Power\(((?:(?!Power\().) ?),(\d )\)/"((". $1 . ")" . ("*(" . $1 . ")") x ($2-1) . ")"/e){}' file.txt

See the online demo:

#!/bin/bash
s='Power(25,2)  Power(225,4)'
perl -pe 'while(s/Power\(((?:(?!Power\().) ?),(\d )\)/"((". $1 . ")" . ("*(" . $1 . ")") x ($2-1) . ")"/e){}' <<< "$s"
# => ((25)*(25))  ((225)*(225)*(225)*(225))

The /e flag treats the RHS as an expression, the replacement is built dynamically, and the repetitions are made with the help of the x operator. Note that the repetition amount is equal to the number captured into Group 2 minus 1.

  • Related