#!/usr/bin/perl # use strict; use warnings; our @toTest = ( "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(c(d)e", "ab(c)d)e"); our $rxNest; $rxNest = qr {(?x) \( (?: (?>[^()]+) | (??{$rxNest}) )* \) }; testString($_) for @toTest; sub testString { my $string = shift; print "\n$string\n"; print " Match ", $string =~ /$rxNest/ ? "succeeded\n" : "failed\n"; } #### Cont(ains balanced( nested Br(ack)ets )in t)he text Match succeeded Con(tains i(mbalan(ced Br(ack)ets, )one c)lose missing Match succeeded Contains i(mbalan(ced Br(ack)ets, )one op)en m)missing Match succeeded No brackets in this string Match failed Won)ky br(ackets in) this s(tring Match succeeded More wonky br(ackets in) th)is s(tring Match succeeded Just the one( leading bracket Match failed And just th)e one trailing bracket Match failed So(me m(ultip)le n(est(s in) thi)s o)ne Match succeeded Ther(e is( mo(re) de(e)p )nes(ti(n(g i)n (mul)ti)p(l)es) he)re Match succeeded Some d((oub)le b)rackets Match succeeded ab(())cde Match succeeded ab(c(d)e Match succeeded ab(c)d)e Match succeeded #### ... our $rxNest; $rxNest = qr {(?x) ( \( (?: (?>[^()]+) | (??{$rxNest}) )* \) ) }; ... #### ... if($string =~ /$rxNest/) { no strict 'refs'; print " Match succeeded\n"; my $memNo = 1; while(defined ${$memNo}) { print " \$$memNo - ${$memNo}\n"; $memNo ++; } } else { print " Match failed\n"; } ... #### ... our @memoList; our $rxNest; $rxNest = qr {(?x) ( \( (?: (?>[^()]+) | (??{$rxNest}) )* \) ) (?{push @memoList, $+}) ... if($string =~ /$rxNest/) { print " Match succeeded\n"; print " $_\n" for @memoList; } else { print " Match failed\n"; } ... #### Cont(ains balanced( nested Br(ack)ets )in t)he text Match succeeded (ack) ( nested Br(ack)ets ) (ains balanced( nested Br(ack)ets )in t) #### Con(tains i(mbalan(ced Br(ack)ets, )one c)lose missing Match succeeded (ack) (ced Br(ack)ets, ) (mbalan(ced Br(ack)ets, )one c) (ack) (ced Br(ack)ets, ) (mbalan(ced Br(ack)ets, )one c) #### #!/usr/bin/perl # use strict; use warnings; our @toTest = ( "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(c(d)e", "ab(c)d)e"); our @memoList; our ($rxBefore, $rxNest, $rxAfter, $rxWhole); $rxBefore = $rxAfter = qr{([^()]*)}; $rxNest = qr {(?x) ( \( (?: (?>[^()]+) | (??{$rxNest}) )* \) ) (?{push @memoList, $+}) }; $rxWhole = qr{^$rxBefore$rxNest$rxAfter$}; testString($_) for @toTest; sub testString { my $string = shift; @memoList = (); print "\nString: $string\n"; if($string =~ /$rxWhole/) { print " Match succeeded\n"; print " ---------------\n"; print " Before brackets:-\n"; print " $1\n"; print " Bracket pairs:-\n"; print " $_\n" for @memoList; print " After brackets:-\n"; print " $3\n"; } else { print " Match failed\n"; } } #### String: Cont(ains balanced( nested Br(ack)ets )in t)he text Match succeeded --------------- Before brackets:- Cont Bracket pairs:- (ack) ( nested Br(ack)ets ) (ains balanced( nested Br(ack)ets )in t) After brackets:- he text String: Con(tains i(mbalan(ced Br(ack)ets, )one c)lose missing Match failed String: Contains i(mbalan(ced Br(ack)ets, )one op)en m)missing Match failed String: No brackets in this string Match failed String: Won)ky br(ackets in) this s(tring Match failed String: More wonky br(ackets in) th)is s(tring Match failed String: Just the one( leading bracket Match failed String: And just th)e one trailing bracket Match failed String: So(me m(ultip)le n(est(s in) thi)s o)ne Match succeeded --------------- Before brackets:- So Bracket pairs:- (ultip) (s in) (est(s in) thi) (me m(ultip)le n(est(s in) thi)s o) After brackets:- ne String: Ther(e is( mo(re) de(e)p )nes(ti(n(g i)n (mul)ti)p(l)es) he)re Match succeeded --------------- Before brackets:- Ther Bracket pairs:- (re) (e) ( mo(re) de(e)p ) (g i) (mul) (n(g i)n (mul)ti) (l) (ti(n(g i)n (mul)ti)p(l)es) (e is( mo(re) de(e)p )nes(ti(n(g i)n (mul)ti)p(l)es) he) After brackets:- re String: Some d((oub)le b)rackets Match succeeded --------------- Before brackets:- Some d Bracket pairs:- (oub) ((oub)le b) After brackets:- rackets String: ab(())cde Match succeeded --------------- Before brackets:- ab Bracket pairs:- () (()) After brackets:- cde String: ab(c(d)e Match failed String: ab(c)d)e Match failed #### #!/usr/bin/perl # use strict; use warnings; our @toTest = ( "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(c(d)e", "ab(c)d)e"); our @memoList; our $rxNest; $rxNest = qr {(?x) ^ ([^()]*) ( \( (?: (?>[^()]+) | (??{$rxNest}) )* \) ) (?{push @memoList, $+}) ([^()]*) $ }; testString($_) for @toTest; sub testString { my $string = shift; @memoList = (); print "\nString: $string\n"; if($string =~ /$rxNest/) { print " Match succeeded\n"; print " ---------------\n"; print " Before brackets:-\n"; print " $1\n"; print " Bracket pairs:-\n"; print " $_\n" for @memoList; print " After brackets:-\n"; print " $3\n"; } else { print " Match failed\n"; } } #### String: Cont(ains balanced( nested Br(ack)ets )in t)he text Match failed String: Con(tains i(mbalan(ced Br(ack)ets, )one c)lose missing Match failed String: Contains i(mbalan(ced Br(ack)ets, )one op)en m)missing Match failed String: No brackets in this string Match failed String: Won)ky br(ackets in) this s(tring Match failed String: More wonky br(ackets in) th)is s(tring Match failed String: Just the one( leading bracket Match failed String: And just th)e one trailing bracket Match failed String: So(me m(ultip)le n(est(s in) thi)s o)ne Match failed String: Ther(e is( mo(re) de(e)p )nes(ti(n(g i)n (mul)ti)p(l)es) he)re Match failed String: Some d((oub)le b)rackets Match failed String: ab(())cde Match failed String: ab(c(d)e Match failed String: ab(c)d)e Match failed