in reply to Matching nested parens

I would suggest Regexp::Common:

use warnings; use strict; use Data::Dump; use Regexp::Common qw/balanced/; "(a a (a a)(a a))(b b(b)b b)" =~ /$RE{balanced}{-parens=>'()'}/; dd $&, $'; # ("(a a (a a)(a a))", "(b b(b)b b)")

Though of course there are plenty of other solutions, including Parse::RecDescent, though that might be a little overkill if this is all you're doing. See e.g. regex for nested "<"/">', and note that Text::Balanced is a core module.

Replies are listed 'Best First'.
Re^2: Matching nested parens
by BernieC (Pilgrim) on Oct 01, 2020 at 21:24 UTC
    Thanks for the advice. Looks like Regexp::Common is just what I wanted {I've just cpan installed it :o)}
      A footnote. I was curious about Regexp::Common. So:
      use Regexp::Common qw/balanced/; say $RE{balanced}{-parens=>'()'} ;
      And I can now see why I didn't have a hope of figuring out the RE on my own... :o)
        ... I didn't have a hope of figuring out the RE on my own...

        This problem is actually used as an an example of the use of (?R) and friends in perlre:

        Win8 Strawberry 5.30.3.1 (64) Thu 10/01/2020 19:06:47 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings use 5.010; # need 5.10+ extended patterns (?R) use Data::Dump qw(dd); my $str = '(a a (a a)(a a))(b b(b)b b) xxx (c (c (c c)))'; my $rx_bal_parens = qr{ \( ( # Capture group 1 (contents of parens) (?: (?> [^()]+ ) # Non-parens without backtracking | (?R) # Recurse to start of regex )* ) \) }xms; my @bal_parens = $str =~ m{ $rx_bal_parens }xmsg; dd \@bal_parens; ^Z ["a a (a a)(a a)", "b b(b)b b", "c (c (c c))"]
        (Of course, if you use something like this, do thorough testing to be sure it really does what you want. :)

        Update: Fixed first line of code (the use 5.010; statement). It somehow got stuck onto the end of the command line during cut-pasting.


        Give a man a fish:  <%-{-{-{-<