my ($code, $simple, $quanti, $regexp); $code = qr/(?: (?: [^{}] # not a curly brackets | \{ (??{ $code }) \} # balanced curly brackets )* )/x; $simple = qr/(?: \\ [pP] \{ \w+ \} # \p{Prop} | \\. # escape | \[ (?: \\. | [^\]] )+ \] # [range] | \( \? \# [^)]+ \) # (?#text) | \( \? [imsx]* -? [imsx]* (?: : (??{ $regexp }) )? \) # (?imsx-imsx) | \( \? (?: [:=!>] | <[=!] ) (??{ $regexp }) \) # (?=pattern) | \( \? \?? \{ (??{ $code }) \} \) # (?{ code }) | \( \? \( (?: \d+ | \? [=!<] (??{ $regexp }) | \? \{ (??{ $code }) \} ) \) (??{ $regexp }) (?: \| (??{ $regexp }) )? \) # (?(1)y|n) | \( (??{ $regexp }) \) # parenthesis | [^\\|()\[\]*+?{}] # single char )/x; $quanti = qr/(?: (?: $simple (?: [+*?] \?? | \{ \d+ (?: , \d* )? \} \?? )? )* )/x; $regexp = qr/(?: $quanti (?: \| $quanti )* )/x; print $regexp =~ /^$regexp$/;