Laeeq
Laeeq

Reputation: 403

Per regex to parse and replace nested match

I have text like below with nested [QUOTE][/QUOTE] tags. I want to parse entire nested string usign Perl regex.

[QUOTE username=test1]This is test one. [QUOTE username=test2]This is test2. [/QUOTE] This is test3 [/QUOTE]

I am using below Perl regex and its parsing first [QUOTE] with its end [/QUOTE] but its not parsing nested tags.

$text =~ s#\[QUOTE\s?(?:username)?(?:=(.*?))?\]([^>]*)?\[\/QUOTE\]#<div class="quoted"><div class="quote-from">$1</div>$2</div>#isg;

It is returning below result with just first [QUOTE] parse and leaving middle [QUOTE][/QUOTE] as it is. But I need to parse all nested tags.

<div class="quoted"><div class="quote-from">test1</div>This is test one. [QUOTE username=test2]This is test2. [/QUOTE] This is test3 </div>

Please help with this.

Upvotes: 2

Views: 176

Answers (1)

rustyx
rustyx

Reputation: 85452

You can achieve it with a couple of changes:

  1. Start replacement from the last matching [QUOTE]
  2. Repeat the regex until no more replacements can be made (since the g flag doesn't backtrack)

Something like this:

1 while $text =~ s#^(.*)\[QUOTE\s*(?:username\s*=\s*([^ \]]+))?\](.*?)\[\/QUOTE\](.*?)#$1<div class="quoted"><div class="quote-from">$2</div>$3</div>$4#s;

The result will be:

<div class="quoted"><div class="quote-from">test1</div>This is test one. <div class="quoted"><div class="quote-from">test2</div>This is test2. </div>This is test3 </div>

Upvotes: 2

Related Questions