Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Checking for numbers and a period

by andrew (Acolyte)
on Jul 20, 2002 at 22:55 UTC ( #183695=perlquestion: print w/replies, xml ) Need Help??
andrew has asked for the wisdom of the Perl Monks concerning the following question:

Ok one of my fields is a price, so I need to check it in a an if statement to see if it contains numbers and or period.

Replies are listed 'Best First'.
Re: Checking for numbers and a period
by Corion (Pope) on Jul 20, 2002 at 23:03 UTC

    It seems like you got it all down - so where is your question ?

    I'll employ Psi::ESP and try to guess - you want to know how to check that a scalar contains a string that can be interpreted as a valid number - this is easy, as long as your definition of "number" is sane.

    As you're talking about "price", I guess that your convention of "number" is "at least one digit from the range of 0 to 9, possibly followed by more such digits, possibly followed by a dot (to delimit the decimals), and then, if there was a dot, two more digits from the range 0 to 9".

    After you've accepted this definition or have come up with your own definition, we need to translate this definition into a regular expression, since that's the easiest way of doing such things like conformance checks, as soon as you know regular expressions :

    my $price = "100.09"; if ($price =~ / ^ # We begin at the start of the string [0-9]+ # At least one digit, possibly followed by more ( # Then (possibly, see below) follows \. # a dot [0-9][0-9] # and two more digits )? # But the decimal part is optional $ # And that's all there is to be /x) { } elsif { die "'$price' dosen't look like a valid price.\n" };

    Update: Please do note that my guessed definition of "number" differs at least from BUUs definition of "number" below. It's not hard to come up with a solution that includes BUUs definition as well, but personally, I think a number should ALWAYS start with a digit from the range 0 to 9.

    To add a support for the weird definition which allows a number to start with a period, use the following RE :

    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web

      For the sake of completness, we should also throw in numbers that start with a comma ",". Much of continental europe use number of the form 123 456,789 to be what we would normally right as 123,456.789

      Of course, if the number supplying audience includes a few mathematicians or science types, we might also encounter numbers such e^12 (where e=2.718... (or somethng)).

      Only problem is it fails on ".23" =[

      The logical answer there is to do:
      but of course that matches litterally everything. So good luck
Re: Checking for numbers and a period
by flocto (Pilgrim) on Jul 20, 2002 at 23:00 UTC

    One way to do this would be:

    my $price = "123.45"; if ($price =~ m/^\d*\.\d{2}$/) { .. }

    For more pattern matching related questions please read the perlre manpage..

    Regards, -octo

Re: Checking for numbers and a period
by ehdonhon (Curate) on Jul 21, 2002 at 02:40 UTC
Re: Checking for numbers and a period
by krusty (Hermit) on Jul 21, 2002 at 03:02 UTC
    So the possibilities are that a price might fall into the following catagories:

    1) 300.25
    2) 300.
    3) 300
    4) .25

    or if you want to visit Europe, replace the periods with commas.
    my $price = $some_price_formatted_like_above; if ($price =~ /\d+[.,]?\d*|[.,]\d+/) {...}
    ...where the first portion of the pattern matches the first three possible formats listed above and the second portion matches a format like .25.
    Have I missed any formats?

    UpdatePlease include the anchors ^$ as in Corion's update. It will prevent the if statement from running as my code would return true for 300.25.25.
    Corion's code misses fractions of cents. Like if something is 99 and 1/2 cent. This may be a desirable trait though. My code misses the European spaces. All the code I've seen so far also misses things like 1,000,000,000.25. This can still be written for, but how far do you really need to go to accomplish your task?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://183695]
and !@monks...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2017-03-26 03:50 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (313 votes). Check out past polls.