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

IT's not counting...

by Dwood (Acolyte)
on Nov 16, 2010 at 07:02 UTC ( [id://871649]=perlquestion: print w/replies, xml ) Need Help??

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

My program is trying to read from a line and count the number of parentheses however, as you can see it's not working very well: My code runs, but does not work, as no matter what either both l_count and r_count are the same or it throws an error about the parentheses not being balanced properly...

How do I count the # of Parentheses in a string? Edit: samarzone fixed me up right and showed me what I was doing wrong. It has thus been fixed:

sub parenth { my ($string) = (@_); my $l_count = () = ($string =~ /\(/g); my $r_count = () = ($string =~ /\)/g); if ($l_count != $r_count) { print "There is no balance on this line! Did you format it + correctly???"; return 0; } else { print "There is balance in this universe"; return 1; } }
Any thoughts on how to implement such parsing methods without regex (is that even possible?)

Or just ideas in general for uses, as such?

Replies are listed 'Best First'.
Re: IT's not counting...
by samarzone (Pilgrim) on Nov 16, 2010 at 07:25 UTC

    1. You are assigning an array to a scalar ($string = (@_)). Value of $string becomes a numeric representing the number of elements in @_
    2. $testString does not seem to be initialized
    3. You need not specify single quotes to enclose brackets. Escaping is enough.
    4. In your example only those brackets will be considered which have an digit following immediately.

    Depending on how complex you want to be, the program may require many changes but taking the simplest approach, I think following will suit your requirements.

    #!/usr/bin/perl use strict; sub parenth { my ($string) = (@_); my $l_count = () = ($string =~ /\(/g); my $r_count = () = ($string =~ /\)/g); if ($l_count != $r_count) { print "There is no balance on this line ($l_count vs $ +r_count)! Did you format it correctly???"; return 0; } else { print "There is balance in this universe"; return 1; } } my $test_string = 'x = (89 - 12)*( 1 + 2)'; parenth($test_string);
      @ point one: Oops, thanks for pointing that out! I was poring over perldoc trying to find stuff about subroutines and saw some things that mentioned exactly what you pointed out and didn't think anything of it...

      Lately my perl debug console has gone all wonky and completely refuses to give me the errors on a per-line basis so I have to hunt down the bugs for each time the errors occur...

      @ point two: Heh, yeah, I just noticed that testString wasn't initialized. Silly me, I was doing tests to see what would work and in my rush to post it, forgot to set it so that testString was $string.

      @ point three & four: Thanks, I'm new to regex and have been avoiding it because of the fairly famous quote that says something about using regex and the programmer now having 2 problems. (obfuscation not good for my diet of perl)

      What kind of changes do you mean?

      Also, thanks for helping me out here! Saved me some hours of searching around haha!
        What kind of changes do you mean?

        By "many changes" I mean that my approach is simply to match number of right brackets against number of left brackets which would return true even in following cases

        • $test_string = 'x = )(';
        • $test_string = 'x = 1*)))*2(((';
        etc.

        For additional constraints, you'll have to think about combination of possible correct/incorrect cases before you could claim that your script is working as expected.

Re: IT's not counting...
by jwkrahn (Abbot) on Nov 16, 2010 at 07:26 UTC

    You say that you are trying to count parentheses but you are using the patterns /'\('\d+/ and /'\)'\d+/ which count the string consisting of a parenthesis surrounded by single quotes followed by one or more numerical digits.

    If you just want to count parentheses then use:

    my $l_count = $testString =~ tr/(//; my $r_count = $testString =~ tr/)//;
      If you don't want to clobber the $testString contents, you could change as below, and add parentheses for clarity (not sure if that is returning in a list context, then assigning to a scalar, but I have seen that idiom many times before).

      my $l_count = ($testString =~ tr/(/(/); my $r_count = ($testString =~ tr/)/)/);

        As jwkrahn had pointed out, the string is not clobbered by his code. You need to supply the d flag to actually delete the characters.

        knoppix@Microknoppix:~$ perl -E ' > $str = q{3 * (4 + 5) / (6 - 7)}; > say $str; > $lb = $str =~ tr/(//; > $rb = $str =~ tr/)//; > say qq{left : $lb}; > say qq{right: $rb}; > say $str; > $dig = $str =~ tr/0-9//d; > say qq{digit: $dig}; > say $str;' 3 * (4 + 5) / (6 - 7) left : 2 right: 2 3 * (4 + 5) / (6 - 7) digit: 5 * ( + ) / ( - ) knoppix@Microknoppix:~$

        I hope this is helpful.

        Cheers,

        JohnGG

        If you don't want to clobber the $testString contents

        Both:

        my $l_count = $testString =~ tr/(//; my $r_count = $testString =~ tr/)//;

        and:

        my $l_count = ($testString =~ tr/(/(/); my $r_count = ($testString =~ tr/)/)/);

        do exactly the same thing.    Neither of which "clobbers" the string.

        not sure if that is returning in a list context

        The left-hand side of the assignment determines context, in this case scalar, so the parentheses are irrelevant.

        I made an oops before I posted!

        $testString is supposed to be the local $string! A leftover from when I was just trying to get it to work at all haha! Which gives us more room to work with since you know that we can do whatever we want as long as the number of parentheses are counted!

        And I don't really want to use too much regex (not much understanding of regex) if I can avoid it. (Why on earth did I try making a simple line parser? :P )

        As a note, samar pointed me to what I think I'll need... but eventually the concept will have to be expanded eventually to fit my needs...

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2024-03-19 04:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found