Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: getting a return code from a looping regular expression

by BlaisePascal (Monk)
on Aug 01, 2000 at 17:40 UTC ( [id://25455]=note: print w/replies, xml ) Need Help??


in reply to getting a return code from a looping regular expression

The regex in the while works by removing all balanced pairs of parentheses, from the inside-out. Your code with the "print" should print 1111111 for both strings. The difference is that at the end, the first string will become 'aio' and the second will become 'aio)'. Something like:
@foo = ('a(b(c)d(e(f)g)h)i(j(k)l(m)n)o', 'a(b(c)d(e(f)g)h)i(j(k)l(m)n)o'); for (@foo) { print "\'$_\' has "; while s/[(][^()][)]//; # get rid of matched () print "un" if /[()]/; # see if any unmatched print "balanced parentheses" }
should work.

Replies are listed 'Best First'.
RE: Re: getting a return code from a looping regular expression
by DrManhattan (Chaplain) on Aug 01, 2000 at 19:32 UTC

    while s/[(][^()][)]//; is actually a syntax error. Also, that pattern only matches parenthesis with exactly one character between them.

    Here's some working code for arbitrary parenthesized strings:

    sub balanced { $_ = shift; while (s/[(][^()]*[)]//) {}; return 0 if /[()]/; return 1; }

    Of course a real programmer uses a PDA to balance parenthesis. (;

    sub balanced { my $string = shift; my $stack = 0; for my $index (0..length($string) - 1) { my $char = substr($string, $index, 1); if ($char eq '(') { $stack++; } elsif ($char eq ')') { $stack--; }
                    # Update: Ha!  Thanks, BlaisePascal.
                    # A PDA that happily pops an empty
                    # stack isn't very useful. :)
    return 0 if $stack < 0; } return $stack ? 0 : 1; }

    -Matt

      True, PDA's are the proper tool for balancing parenthesis. But it helps if it works... Your PDA would match "))((" perfectly find. Most wouldn't consider that balanced...
      sub balanced { my $string = shift; my $stack = 0; @string = split //, $string; for (@string) { last if $stack < 0; $stack++ if /[(]/; $stack-- if /[)]/; } return $stack ? 0 : 1; }
      or, without using split and //:
      sub balanced { my $string = shift; my $stack = 0; for my $i (0..length($string)-1) { last if $stack < 0; $stack++ if substr($string,$i,1) eq '('; $stack-- if substr($string,$i,1) eq ')'; } return $stack ?0 : 1; }
RE: Re: getting a return code from a looping regular expression
by maverick (Curate) on Aug 01, 2000 at 19:30 UTC
    hmmm...code produced a syntax error for me on the while line.
    @foo = ('a(b(c)d(e(f)g)h)i(j(k)l(m)n)o', 'a(b(c)d(e(f)g)h)i(j(k)l(m)n)o)'); for (@foo) { print "\'$_\' has "; while ( s/\([^()]*\)// ){} print "un" if /[()]/; print "balanced parentheses\n"; }
    Just a few minor modifications.

    While you can use an algorithm like this to find if a string has matches parens, you can't write a single regexp that does it. Check out this node for a bit of an explination for this.

    /\/\averick

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://25455]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2024-04-20 00:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found