in reply to Parsing nested parentheses

Once you know how to write a regex to match a string with balanced parens, it's not to hard to write a regex to do what you want.

How does a string with balanced parens look like? It starts with an opening paren, then "junk" separated by strings with balanced parens, where "junk" is a string consisting of something that isn't a paren. Quite like a delimited string with escaped delimiters actually.

Now, how do we go from string with balanced parens to the requested string? Simple. We start with an opening paren, then junk string separated by strings with balanced parens, then "C", then junk strings separated by strings with balanced parens, and finally a closing paren.

So much for text. Here's the code:

#!/usr/bin/perl use strict; use warnings; no warnings qw /syntax/; my $bal; $bal = qr /[(] [^()]* (?:(??{ $bal }) [^()]* )* [)]/x; my $re = qr /[(] [^()]* (?:(??{ $bal }) [^()]* )* C [^()]* (?:(??{ $bal }) [^()]* )* [)]/x; while (<DATA>) { chomp; print "$_: "; print $& if /$re/; print "\n"; } __DATA__ ((A, B), C, (D, E)) (((A, B), C, (D, E))) ((A, B), D, (C, E)) ((A, C), D, (B, E)) (((A, C)), D, (B, E)) ((A, (C)), D, (B, E)) A, B, C, D, E ((A, B), F, (D, E)) ((A, B), C, (D, E)): ((A, B), C, (D, E)) (((A, B), C, (D, E))): ((A, B), C, (D, E)) ((A, B), D, (C, E)): (C, E) ((A, C), D, (B, E)): (A, C) (((A, C)), D, (B, E)): (A, C) ((A, (C)), D, (B, E)): (C) A, B, C, D, E: ((A, B), F, (D, E)):

(I cooked up this regex while I was walking home from the train station. It turned out to work at the first try).

Abigail

Replies are listed 'Best First'.
Re: Re: Parsing nested parentheses
by husker (Chaplain) on Nov 18, 2003 at 22:17 UTC
    (I cooked up this regex while I was walking home from the train station. It turned out to work at the first try).
    Amazing. The most constructive thing I think about on the way home from the train station is if I will be able to get my "welcome home" beer open on the first try.