use re 'eval'; $begin = '[xyz]'; $end = '[/xyz]'; $string = '[xyz]level 1.1 [xyz]level 2.1[/xyz] rest of 1.1 [/xyz]'; $re = qr{ \Q$begin\E (?: (?> (?:(?!=\Q$begin\E|\Q$end\E).)+ ) | (??{ $re }) )* \Q$end\E }x; print 'Yeah!' if $string =~ $re;