my $string = q( Outside. {tag} Inside level 1. {tag} Inside level 2. {/tag} Inside level 1. {/tag} Outside. ); (my $re=$string)=~s/((\{tag\})|(\{\/tag\})|.)/${[')','']}[!$3]\Q$1\E${['(','']}[!$2]/gs; @$ = (eval{$string=~/$re/}); die $@ if $@=~/unmatched/; $re = join("|",map{quotemeta}@$); print $string while $string=~s/\{tag\}($re)\{\/tag\}/--Marked--\n$1\n--EndMarked--/;