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

Why this is work?

by Csonytii (Novice)
on May 29, 2018 at 11:56 UTC ( [id://1215357]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Forum.
Today i wrote a code which is seek for positive or negative number in a line( only 1 in 1 line ), and i don't now why this is work.
#!/usr/bin/perl -w $sum=0; $count=0; open(INPUT,"meres.txt") or die "ERROR"; while($line=<INPUT>) { chomp($line); if($line=~/([-\d]+(\d+)*)/){ #print($1."\n"); $sum+=$1; $count++; } } close(INPUT); print $sum/$count; print "\n";
Well, i understand what pieces i am using but i wonder the logic behind it.
Thanks for your answer

Replies are listed 'Best First'.
Re: Why this is work?
by Veltro (Hermit) on May 29, 2018 at 12:59 UTC

    Hi Csonytii

    I'll focus on your regular expresson /([-\d]+(\d+)*)/

    In your regular expression (regex) you have used the grouping construct (...) twice. Potentially that would result in a value in $1 and $2. But because you said there is only one number in one line this is probably not what you wanted. In your regex you also have used a character group []. The character group you have created means allowing '-' and any number. Then you follow with a '+' meaning one of these characters must appear followed by zero or more of the characters from the character group. (This means also a pattern line '-2-1' is allowed). The last (\d+)* does not seem to be not necessary since it is never reached in this case. The first part of your regex /([-\d]+)/ already 'kind of' does what you want. My suggestion would be something like: /([-+]?\d+)/. This allows zero or one '-' or zero or one '+' followed by a minimum of one number followed by zero or more numbers.

      thank you for your reply!

      now i understand what i did.
Re: Why this is work?
by pme (Monsignor) on May 29, 2018 at 12:52 UTC
    Hi Csonytii,
    #!/usr/bin/perl -w use strict; use warnings; my $sum; my $count; open my $input, '<', 'meres.txt' or die "ERROR: $!\n"; while(my $line = <$input>) { # read line to $li +ne chomp $line; # remove eol if ($line =~ /(-?\d+)/) { # match to numbers + and optional leading minus, the match will be in $1 #print($1."\n"); $sum += $1; # summing up $count++; # count items } } close $input; print 'Average: ', $sum/$count, "\n";
    HTH

    Update:Typo fixed.

      seems a bit cooler code than mine.
      thank you!
Re: Why this is work?
by Jenda (Abbot) on May 31, 2018 at 15:32 UTC

    Actually ... not that you would be likely to get bitten by this, but just as a warning. Someone somewhere decided it'd be cool if \d matched "anything resembling a number in almost any of the writing systems ever used by humans" barely stopping short of matching the roman I, V, X, etc. On the other hand the automatic number conversion only understands 0, 1, 2, ... 9 so not all that matches \d+ may be converted to numbers. It was a bad idea, but I doubt it will ever be fixed.

    If you want to be sure you only get what the rest of Perl considers numerals, use [0-9].

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

      That's a bit narrow, no? Perl considers these numerals: 1_3 (or even 1____3 discounting strictures/warnings), 0xd, 0b1101, and 1.3e1 as you know. If \d should not match things Unicode defines as numbers then logically \w should not match any letters outside ASCII. /a and /u can be used to clarify and limit the regular expression too.

        say ('1_3' + 0); say ('0xd' + 0); say ('0b1101' + 0); say ('1.3e1' + 0);

        Literals are irrelevant, the conversion from string to number is what counts, because that's what's more often than not what happens to the matched string, and only the last one actually works.

        There's no reason whatsoever not to require \p{Number} for the rare use case of "give me anything that might be a digit to someone".

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

Re: Why this is work?
by sundialsvc4 (Abbot) on May 29, 2018 at 14:30 UTC
    Possibly /([+-]?\d+)/) to recognize plus or minus.

      There's no point. The result is the same if you match and include the plus sign and if you ignore it.

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

        Not to mention the fact that he doesn't get the syntax right, even on something so simple.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-03-28 16:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found