Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

Regexp for Match Brackets

by gopalr (Priest)
on May 05, 2006 at 06:33 UTC ( [id://547596] : perlquestion . print w/replies, xml ) Need Help??

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

Dear Monks,

I tried the following code to match the whole brackets which are inside the Main Brackets.

use strict; my $text='(one dfd(two(three)four()(five)df())df)'; print $& if $text=~m#(\([^()]*(\([^()]*\))+[^)]*\))+#;

It Prints only


But I need Out put Whole Opened and Closed Brackets

Need Output:

(one dfd(two(three)four()(five)df())df)

Please advice me in regulare expression

Thanks in Advance,
Gopal R.

Replies are listed 'Best First'.
Re: Regexp for Match Brackets
by davido (Cardinal) on May 05, 2006 at 06:47 UTC

    I'm confused. Please explain how your needed output differs from your original string; they appear the same to me. If you intend to capture everything, please explain what you're trying to not capture, or at least what you would like to fail to match.

    Do you really want Text::Balanced's extract_bracketed() subroutine? It can be used to essentially capture the "balanced parens" portion of a string. Observe:

    use strict; use warnings; use Text::Balanced qw( extract_bracketed ); my $text='(one dfd(two(three)four()(five)df())df)'; my $balanced = extract_bracketed( $text ); print "$balanced\n";

    Also note, if the return value of extract_bracketed() is undef (in scalar context), it means the parens weren't balanced.


Re: Regexp for Match Brackets
by Samy_rio (Vicar) on May 05, 2006 at 07:12 UTC

    Hi gopalr, If I understood your question correctly then try this,

    use Regexp::Common; while (<DATA>) { (/$RE{balanced}{-begin => "("}{-end => ")"}/) ? (print "Line $. : Matc +hed: $&\n") : (print "Line $. : Not Matched\n"); } __DATA__ This is my (one dfd(two(three)four()(five)df())df) text. This is my (one text.

    Output is :

    Line 1 : Matched: (one dfd(two(three)four()(five)df())df) Line 2 : Not Matched

    Velusamy R.

    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

Re: Regexp for Match Brackets
by blazar (Canon) on May 05, 2006 at 08:48 UTC

    This kind of match is notoriously hard to perform. Try some dedicated module like Text::Balanced. OTOH I'm sure I saw at least one very in-depth article explaining how to do it with regexen. I can't remember where to find it. I bet japhy knows, though...


      Oh, it's blazar. Simply put, to do it with regexes, you'd do something like:

      my $paren_rx; $paren_rx = qr{ \( (?: (??{ $paren_rx }) # either match another paren-set | (?s: [^\\()]+ | \\. )+ # or match non-parens (or escaped parens +) )? \) }x; my ($chunk) = $string =~ /((??{$paren_rx}))/;
      It's not kid-tested, nor mother-approved, but it feels right, and that's where it counts. In the gut. Long live truthiness. Stephen Colbert++.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

        Yes, but I seem to remember an article, perhaps downloadable in .pdf form that explained "this kinda things" in detail and from step to step. The OP could be interested in it...

Re: Regexp for Match Brackets
by sen (Hermit) on May 05, 2006 at 06:50 UTC

    hi Gopal, try this one

    print $& if $text=~m#(\(.*\))#;

      the problem of your solution is that it takes all the text (parenthesis included) between the first open parenthesis and the last closed parenthesis, even if they are not balanced! :-P


      perl -Te 'print map { chr((ord)-((10,20,2,7)[$i++])) } split //,"turo"'
Re: Regexp for Match Brackets
by ruzam (Curate) on May 05, 2006 at 16:28 UTC
    If all you want to do is test for an equal number of '(' and ')' then this will do the trick:
    use strict; my $text='(one dfd(two(three)four()(five)df())df)'; print $text if (my @x = $text =~ m/\(/g) == (my @y = $text =~ m/\)/g);
    This counts up the number of '(' and the number of ')' and prints $text if the counts equal.

    Note: this doesn't test if the brackets are balanced! $text=')()(()' would match just as easily as $text='((()))'

    Also, I don't think using $& is a good idea for this problem.
Re: Regexp for Match Brackets
by gube (Parson) on May 05, 2006 at 07:15 UTC
    #!/usr/local/bin/perl use strict; use warnings; my $text='(one dfd(two(three)four()(five)df())df)'; print $& if $text=~m#(.*)#;