At 01:19 AM 10/19/01 +0100, Ian Phillipps wrote:
>On Thu, 18 Oct 2001 at 18:33:53 -0400, Selector, Lev Y wrote:
> > Wow! This is really elegant !!
>
> > -----Original Message-----
> > From: Josh Goldberg [mailto:[EMAIL PROTECTED]]
>
> > sub isNumber {
> > !/\d/ ? 0 : $_ == 0 ? 1 : $_ * 1
> > }
>
>Possibly elegant, but definitely not correct.
>
>Anything non-numeric, but with digits in, will generate an ugly warning
>and incorrectly return "1". Try 'foo0' and you'll see what I mean.
>You did try the -w switch, didn't you?
>
>I prefer Lev's original, and offer this as an improvement:
>
>sub isNumber($){
> $_[0] =~ /^(?=[-+.]*\d)[-+]?\d*\.?\d*(?:e[-+ ]?\d+)?$/i
>}
>
>The initial zero-width assertion is to prevent ".e5" from being a
>number, while permitting "123.".
>
>The space after the "e" is in deference to FORTRAN, which writes numbers
>like "1.23E 01". But that's a matter of taste.
>
>I feel sure this is a FAQ...
Amazingly, so does "perldoc -q number":
How do I determine whether a scalar is a
number/whole/integer/float?
Assuming that you don't care about IEEE notations like
"NaN" or "Infinity", you probably just want to use a
regular expression.
if (/\D/) { print "has nondigits\n" }
if (/^\d+$/) { print "is a whole number\n" }
if (/^-?\d+$/) { print "is an integer\n" }
if (/^[+-]?\d+$/) { print "is a +/- integer\n" }
if (/^-?\d+\.?\d*$/) { print "is a real number\n" }
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal number" }
if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
{ print "a C float" }
If you're on a POSIX system, Perl's supports the
"POSIX::strtod" function. Its semantics are somewhat
cumbersome, so here's a "getnum" wrapper function for more
convenient access. This function takes a string and
returns the number it found, or "undef" for input that
isn't a C float. The "is_numeric" function is a front end
to "getnum" if you just want to say, ``Is this a float?''
sub getnum {
use POSIX qw(strtod);
my $str = shift;
$str =~ s/^\s+//;
$str =~ s/\s+$//;
$! = 0;
my($num, $unparsed) = strtod($str);
if (($str eq '') || ($unparsed != 0) || $!) {
return undef;
} else {
return $num;
}
}
sub is_numeric { defined getnum($_[0]) }
Or you could check out the String::Scanf module on CPAN
instead. The POSIX module (part of the standard Perl
distribution) provides the "strtod" and "strtol" for
converting strings to double and longs, respectively.
--
Peter Scott
Pacific Systems Design Technologies
http://www.perldebugged.com