in reply to Eternal question of parsing parentheses

Eternal answer RTFM¹ ! :)

perldoc perlre ( >5.10) and searching for "recursive" brought the following code, where I only had to exchange "foo" with \w*

$_='a(b(c(d)(e))f)g(h)((i)j)'; $re = qr{ ( # paren group 1 (full function) \w* ( # paren group 2 (parens) \( ( # paren group 3 (contents of parens) (?: (?> [^()]+ ) # Non-parens without backtracking | (?2) # Recurse to start of paren group 2 )* ) \) ) ) }x; @matches=/$re/; print "@matches";

perl /tmp/tst.pl a(b(c(d)(e))f) (b(c(d)(e))f) b(c(d)(e))f Compilation finished at Sat Oct 24 19:42:58

Cheers Rolf

(¹) SCNR 8)

UPDATE: untabified code.

Replies are listed 'Best First'.
Re^2: Eternal question of parsing parentheses
by LanX (Saint) on Oct 24, 2009 at 20:13 UTC
    Hi

    I simplified the code, and replaced tr/()/<>/ to make it more readable:

    $_='a<b<c<d><e>>f>g<h><<i>j>'; $re = qr{ < # anchor at first paren as wanted ( # paren group 1 (?: (?> [^<>]+) # Non-parens without backtracking | < (?1) # Recurse to start of paren group 1 > )* ) }x; /$re/; print $1;
    perl /tmp/tst2.pl b<c<d><e>>f

    Cheers Rolf

Re^2: Eternal question of parsing parentheses
by AnomalousMonk (Archbishop) on Oct 24, 2009 at 18:46 UTC
    For those still limited to 5.8 and before, see also the discussion of the
     (??{ code }) construct under Extended Patterns (just before the discussion of
    (?PARNO)) in perlre.