$re = qr /begin # Start with 'begin', (?: # Followed by (?>[^be]+) # Not a b or e, many times, |b(?!egin) # Or a b not starting 'begin', |e(?!nd) # Or an e not starting 'end', |(??{ $re }) # Or a balanced begin/end block )* # zero or more times end/x; # And an 'end'.