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

I would not normally post such a simple question but: My current *debugging* code:
use strict; while (<DATA>) { chomp; my $input = $_; tr/$, +//d; if (/^[-]?\d+$/) { print "Acceptable: '$input' -> $_\n"; } elsif (/^[-]?\d+\.[\d]+$/) { ## problem print "Acceptable: '$input' -> ", int $_, "\n"; } else { print "Not acceptable: '$input' -> $_\n"; } } __DATA__ +30 -400 +20,0 -300.02 $ -50.1 -$ 500 - $ 60 + $ 30.
All the example data is acceptable. I don't need a one-regex-fits-all solution--readability is more important. Rounding is unnecessary. Blanks outside of the numeric component are allowable but should be eliminated from the results. I'm not sure how to correct *problem* expression to handle the last test case (and it may allow undesirable things I'm not aware of). Here is the output from the above code:
Acceptable: '-400' -> -400 Acceptable: '+20,0' -> 200 Acceptable: '-300.02' -> -300 Acceptable: '$ -50.1' -> -50 Acceptable: '-$ 500' -> -500 Acceptable: '- $ 60' -> -60 Not acceptable: ' + $ 30.' -> 30.
Thanks in advance for any help!

--Jim

Replies are listed 'Best First'.
Re: Validating specific numeric input
by VSarkiss (Monsignor) on May 02, 2002 at 18:57 UTC

    Try this: if (/^-?\d+\.\d*$/)Incidentally, you could combine the two tests into one regexp, but it looks like you want to keep the distinction between those with decimal points and those without. If not, you could do this: if (/^-?\d+(\.\d*)?$/) Note that this second one will capture the fractional part, if any. If that's undesirable, do: if (/^-?\d+(?:\.\d*)?$/) HTH

      Thanks so much! The second one does what I want (from what little bit of testing I've done). What I have so far looks like this now, after incorporating they suggestions by tadman and yourself:
      use strict; while (<DATA>) { chomp; my $input = $_; tr/$, +//d; if (/^-?\d+(\.\d*)?$/) { print "Acceptable: '$input' -> ", int $_, "\n"; } else { print "Not acceptable: '$input' -> $_\n"; } } __DATA__ +30 -400 +20,0 -300.02 $ -50.1 -$ 500 - $ 60 + $ 30.
      Output:
      Acceptable: '-400' -> -400 Acceptable: '+20,0' -> 200 Acceptable: '-300.02' -> -300 Acceptable: '$ -50.1' -> -50 Acceptable: '-$ 500' -> -500 Acceptable: '- $ 60' -> -60 Acceptable: ' + $ 30.' -> 30
      If there are anymore optimizations, corrections feel free to kibitz. Thanks all!

      --Jim

Re: Validating specific numeric input
by tadman (Prior) on May 02, 2002 at 18:50 UTC
    Just as a note, you probably mean to use rounded brackets instead of square ones in your regex. The square brackets are used for "sets". [\d] is exactly the same as \d, but not (\d).

    Secondly, try to escape regex-type characters, such as dash, dot and so forth. /-/ versus /\-/.
      Ah, thanks. In my haste to whip something together I mistakenly thought that the square brackets indicated "optional" characters/metacharacters. That would partially explain why the last data example doesn't pass since it requires one or more digits to follow the period.

      --Jim

Re: Validating specific numeric input
by Fletch (Bishop) on May 02, 2002 at 19:43 UTC
    perldoc -q "is a number"
      Thanks for the reference. if (/^-?\d+\.?\d*$/) { print "is a real number\n" } also appears to do what I want. Unfortunately the only reference I checked was the Perl Cookbook, which contains the same expression, but with a slightly vague comment: warn "not a decimal number" unless (/^-?\d+\.?\d*$/); #rejects .2 At the time it looked as if it wouldn't suit my needs. Upon closer examination, which I only had time for thanks to tadman and VSarkiss, I wouldn't really care to receive any value less than one, but I planned to replace any unacceptable values with zero anyhow.

      --Jim