Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
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 pondering the Monastery: (8)
As of 2020-10-26 14:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (251 votes). Check out past polls.

    Notices?