http://www.perlmonks.org?node_id=130375

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

I was able to program my script to reject anything that is not a number. However, it also rejects numbers that have a decimal point too. So, if I enter a number like 3.45, it will reject that and not continue until I have entered a number like 3. Here is the code:
my $LENGTH = 0; while (1) { print "Enter the length!"; "\n"; chomp ($LENGTH = <>); # checking for non-numeric characters if ($LENGTH =~ /\D/){ print "\nPlease enter a number\n"; next; } last if 0 <= $LENGTH and $LENGTH <= 99.99; }
Thanks in advance, Bill Hoefer

Replies are listed 'Best First'.
Re: Verifying number input
by footpad (Abbot) on Dec 08, 2001 at 08:28 UTC
Re: Verifying number input
by japhy (Canon) on Dec 08, 2001 at 06:42 UTC
    This is in the FAQ.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Verifying number input
by rob_au (Abbot) on Dec 08, 2001 at 15:49 UTC
    In addition to the excellent leads given by footpad above, I might just also throw Regexp::Common written by Damian Conway into the mix. This module provides a number of regular expressions for everyday use - For example, from the documentation POD:

    use Regexp::Common; while (<>) { /$RE{num}{real}/ and print q{a number\n}; /$RE{quoted}/ and print q{a ['"`] quoted string\ +n}; /$RE{delimited}{-delim=>'/'}/ and print q{a /.../ sequence\n}; /$RE{balanced}{-parens=>'()'}/ and print q{balanced parentheses\n +}; /$RE{profanity}/ and print q{a #*@%-ing word\n}; }

    In addition to this, Regexp::Common allows the specification and matching of {real} and {int} numbers, numbers of differing base and those separated into groups by a specified separator.

    Definitely worth a look at ... TheDamian++

     

    perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'

Re: Verifying number input
by dvergin (Monsignor) on Dec 08, 2001 at 09:00 UTC
    A few comments. First, you appear to be using "use strict;". That's a good sign. It will save you a lot of grief in the long run.

    You are using some indenting. But it is deceptive -- the indenting doesn't correspond to what you are doing. And several aspects of your logic would be much clearer with the help of some indenting that made the flow of your code clear.

    Finally, and in answer to your question, here is a slightly re-worked version of your code that does what you want. Note that I also put in a feedback line for the 0-99.99 test that you do.

    my $length = 0; while (1) { print "Enter the length: "; chomp ($length = <>); # checking for non-numeric characters unless ($length =~ /^[\d.]+$/){ print "\nPlease enter a number\n"; next; } last if 0 <= $length and $length <= 99.99; print "It must be between 0 and 99.99\n"; }
    Your regex tested to see if there was anything that was not a digit. This approach /^[\d.]+$/ tests to see if between the beginning and the end of the string there are one or more characters that can only be digits or a period. If any other character appears in the string, the test fails.

    There are other ways to attack this, but I have stayed fairly close to your logic. Hope this helps.

    David

    Update: coolmichael is right, of course. A revised regex might be: /^\d+(\.\d+)?$/

    ------------------------------------------------------------
    "Perl is a mess and that's good because the
    problem space is also a mess.
    " - Larry Wall

      For the most part, that will work but it will also match strings like 99.23.8427. I'm not sure if it will be a problem for the poster though, I just thought it important to point out.

      Michael.