Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

RegEx for Matching paranthesis

by Anonymous Monk
on Feb 17, 2004 at 14:25 UTC ( #329597=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I need to extract a text in between nested paranthesis, and I would like to have the text in between the outermost one. For eg., if the text is given as <code start>I am (giving this (text to (tell you) that this) will give) you the result.<code end> In this case, I need the phrase, (giving this (text to (tell you) that this) will give) This should hold for any number of nested paranthesis. Is there a way to achieve this using Regular Expressions? Or is it the conventional way that is best suited for this? Is there a function which can give the matching paranthesis locations in a given string? As I am a beginner to Regular Expressions of Perl, a code snippet would be of immense help to me.

Replies are listed 'Best First'.
Re: RegEx for Matching paranthesis
by larsen (Parson) on Feb 17, 2004 at 14:38 UTC
    Perl is nice: you can solve your problem remaining a beginner in Regexp :)) (just kidding): take a look at Text::Balanced, maybe it can help you.
Re: RegEx for Matching paranthesis
by Roger (Parson) on Feb 17, 2004 at 15:21 UTC
    I would recommend using the CPAN module as suggested by larsen. However I am presenting this solution just for fun... :-)
    use strict; use warnings; my $str = 'I am (giving this (text to (tell you) that this) will give) + you the result)))'; my $match = ''; { local $_ = $str; my $n = 0; s/([()]|.)/ if ($1 eq '(') { $n++; $match .= $1 } elsif ($1 eq ')') { if ($n) { $n--; $match .= $1 } } else { $match .= $1 if $n } /gex; } print "$match\n"; __END__ # output (giving this (text to (tell you) that this) will give)

Re: RegEx for Matching paranthesis
by Taulmarill (Deacon) on Feb 17, 2004 at 14:36 UTC
    if you want only the text betwen the most left "(" and the most right ")" then this should do:
    /^[^(]*(.*?)[^)]*$/

    ---edit---

    oh, yes, after
    $text =~ /^[^(]*(.*?)[^)]*$/;
    the snippet you want is in $1.
Re: RegEx for Matching paranthesis
by borisz (Canon) on Feb 18, 2004 at 00:48 UTC
    Here is a regex taht match nested braces.
    my $match; $match = qr/(?:\((?:(?>[^\(\)]+)|(??{$match}))*\))/; if ( $text =~ /($match)/ ) { print $1; # text between nested ( and ) }
    Boris
Re: RegEx for Matching paranthesis
by I0 (Priest) on Feb 18, 2004 at 01:49 UTC
    $_ = qq(For eg., if the text is given as <code start>I am (giving this (text to (tell you) that this) will give +) you the result. <code end> In this case, I need the phrase, (giving this (text to (tel +l you) that this) will give) This should hold for any number of nested paranthesis.); (my $re = $_) =~ s/((\()|(\))|.)/${['(','']}[!$2]\Q$1\E${[')','']}[!$3 +]/gs; print eval{(/$re/)[0]},"\n"; warn $@ if $@;
Re: RegEx for Matching paranthesis
by eyepopslikeamosquito (Bishop) on Feb 18, 2004 at 07:53 UTC

    See perlfaq6 "Can I use Perl regular expressions to match balanced text?" but be sure you're looking at a recent version (Perl 5.8 or above) since earlier versions don't mention the excellent Text::Balanced solution.

    It's also discussed in the Perl Cookbook, Recipe 6.17 (Matching Nested Patterns).

    /-\

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://329597]
Approved by physi
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2020-10-31 02:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (286 votes). Check out past polls.

    Notices?