ccn has asked for the wisdom of the Perl Monks concerning the following question:

I've added an \A ancor to well-known regexp from perldoc perlre which matches nested parens. But it doesn't match what I want.
use strict; use warnings; no warnings qw /uninitialized/; my $re = qr{\A \( (?: (?> [^()]+ ) # Non-parens without backtracking | (??{ $re }) # Group with matching parens )* \) }x; while (<DATA>) { chomp; print "$_: "; print $& if /$re/; print "\n"; } __DATA__ (*********) (***(*)***) ((***)) (((***))) ((**)**(**)) (((())))
/usr/local/bin/perl -w /home/ccn/ab.pl 
(*********): (*********)
(***(*)***): 
((***)): 
(((***))): 
((**)**(**)): 
(((()))): 

Replies are listed 'Best First'.
Re: Why this regexp doesn't match nested parens?
by broquaint (Abbot) on Apr 26, 2004 at 16:40 UTC
    Using the \A anchor will make the regex fail as soon as it recurses since it will try to match the beginning of the string (hence only the first example string succeeding in your case). If you're matching nested parens then Regexp::Common::balanced can help you out e.g
    use Regexp::Common; my @examples = qw/ (*********) (***(*)***) ((***)) (((***))) ((**)**(**)) (((()))) /; for( @examples ) { chomp; print "$_: "; print $& if $_ =~ $RE{balanced}{-parens=>'()'}; print "\n"; } __output__ (*********): (*********) (***(*)***): (***(*)***) ((***)): ((***)) (((***))): (((***))) ((**)**(**)): ((**)**(**)) (((()))): (((())))
    HTH

    _________
    broquaint

      thanks, I mess that
Re: Why this regexp doesn't match nested parens?
by japhy (Canon) on Apr 26, 2004 at 16:50 UTC
    You also fall prey to using a my() variable in the same line that you declared it:
    use strict; use warnings; # DON'T turn off the uninit warning my $x = qr/(a(??{$x})?b)/; print "x1($1)\n" if "alphabet" =~ $x; print "x2($1)\n" if "caaabbbc" =~ $x; my $y; $y = qr/(a(??{$y})?b)/; print "y1($1)\n" if "alphabet" =~ $y; print "y2($1)\n" if "caaabbbc" =~ $y; __END__ output: Use of uninitialized value in pattern match (m//) at rx line 2. x1(ab) x2(ab) y1(ab) y2(aaabbb)
    See? The $x regex is looking for $main::x (although it doesn't give you a strict-breakage, since it's not looking for package names in the code that handles (??{ })), and it's empty, so you get a warning.

    Take out the \A anchor, but also declare the variable first and then assign to it.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;
      Thanks, japhy, you are right
Re: Why this regexp doesn't match nested parens?
by jryan (Vicar) on Apr 26, 2004 at 19:42 UTC

    The easy solution to your regex problem (although Text::Balanced is probably an easier solution to your general problem) is to just maintain modularity:

    use strict; use warnings; no warnings qw /uninitialized/; # \A anchor removed, so this is the same regex from the perlfaq. my $re; $re = qr{ \( (?: (?> [^()]+ ) # Non-parens without backtracking | (??{ $re }) # Group with matching parens )* \) }x; while (<DATA>) { chomp; print "$_: "; # here is the proper place for the anchor print $& if /\A$re/; print "\n"; } __DATA__ (*********) (***(*)***) ((***)) (((***))) ((**)**(**)) (((())))