secJ
secJ

Reputation: 509

Perl: String Repetition Operator in Substituion Regex

Is there an easy way to use Perl's repetition operator, x, during a substitution regex?

I'm trying to do a quick one-liner on very basic HTML without using a module. Essentially, I'd like to transform lines with opening <h*> and closing </h*> HTML tags into WIKI markup based on the heading number in the HTML tag. So...

___Original DATA___

___Wanted DATA___

Everything works well with the regex itself, capturing the digit needed from the original header tag into the $1 variable. During the substitution portion, is there a way I can use that variable to create the needed number of = signs (e.g., "=" x $1)?

perl -0777 -pe 's/<h(\d)>([^<]*)<\/h\d>/"="x$1 $2 "="x$1/gs', but the latter half ("="x$1 $2 "="x$1) of the command doesn't give me the wanted output.

Upvotes: 0

Views: 194

Answers (3)

Doggerel
Doggerel

Reputation: 87

This version uses a {} delimeter to avoid escape-itis, a /i and a backreference so something like

<h1>.....</h3> 

doesn't get matched.

s{<h(\d)>([^<]*)</h\g1>}{"=" x $1 . " $2 " . "=" x $1}gei;

Upvotes: 0

a3f
a3f

Reputation: 8657

That's what the s///e regex modifier is for:

s/<h(\d)>([^<]*)<\/h\d>/("=" x $1) .$2. ("=" x $1)/gse

Upvotes: 1

choroba
choroba

Reputation: 241928

Operators are not interpolated in strings. You need the /e switch to interpret the replacement as code, not just string:

s/<h(\d)>([^<]*)<\/h\d>/"=" x $1 . $2 . "=" x $1/ge

You can also use a different delimiter instead of / to avoid the need to backslash it in </h.

/s is not needed, as it changes the behaviour of . which doesn't occur in the regex.

Upvotes: 2

Related Questions