#!/usr/bin/perl use strict; use warnings; our $code_re; $code_re = qr{ \( (?: (?>[^()]+) | (??{$code_re}) )* \) }x; our $parno_re = qr{ ( \( (?: (?>[^()]+) | (?-1) )* \) ) }x; while () { chomp; print /^(?:(?>[^()]+)|$code_re)*$/ ? 'PASS' : ' '; print /^(?:(?>[^()]+)|$parno_re)*$/ ? ' PASS' : ' '; print " $_\n"; } __DATA__ + Cont(ains balanced( nested Br(ack)ets )in t)he text - Con(tains i(mbalan(ced Br(ack)ets, )one c)lose missing - Contains i(mbalan(ced Br(ack)ets, )one op)en m)missing + No brackets in this string - Won)ky br(ackets in) this s(tring - More wonky br(ackets in) th)is s(tring - Just the one( leading bracket - And just th)e one trailing bracket + So(me m(ultip)le n(est(s in) thi)s o)ne + Ther(e is( mo(re) de(e)p )nes(ti(n(g i)n (mul)ti)p(l)es) he)re + Some d((oub)le b)rackets + ab(())cde + ab()()cde - ab(c(d)e - ab(c)d)e