#!/usr/bin/perl use strict; use warnings 'all'; use vars qw /$re/; $re = qr /begin (?: (?>[^be])* |(??{ $re }) | [be] )* end/x; sub pass {local $_ = shift; print /^$re$/ ? "ok\n" : "not ok: $_\n"} sub fail {local $_ = shift; print ! /^$re$/ ? "ok\n" : "not ok: $_\n"} pass 'begin end'; fail 'begin en'; fail 'begin nd'; pass 'begin begin end end'; pass 'beginend'; pass 'beginbeginbeginendendend'; pass 'begin begin end begin begin end begin end end end'; fail 'begin begin end begin egin end begin end end end'; fail 'begin end begin end'; __END__ ok ok ok ok ok ok ok not ok: begin begin end begin egin end begin end end end not ok: begin end begin end