my$re = qr/ begin (?: (?> [^be]* ) |(??{ $re }) | [be] )* end /x; foreach () { chomp; my @matches = $_ =~ /($re)/g; print qq(For "$_":\n\t); print (@matches ? join("*",@matches) : "no matches", "\n"); } __DATA__ begin end begin en begin nd begin begin end end beginend beginbeginbeginendendend begin begin end begin begin end begin end end end begin begin end begin egin end begin end end end begin end begin end #### For "begin end": begin end For "begin en": no matches For "begin nd": no matches For "begin begin end end": begin begin end end For "beginend": beginend For "beginbeginbeginendendend": beginbeginbeginendend For "begin begin end begin begin end begin end end end": begin begin end begin begin end begin end end For "begin begin end begin egin end begin end end end": begin begin end begin egin end begin end end For "begin end begin end": begin end*begin end