I know that there is a library that do that
use Scalar::Util qw(looks_like_number);
yet I want to do it using perl regular expression. And I want it to work for double numbers not for only integers.
so I want something better than this
$var =开发者_Python百科~ /^[+-]?\d+$/
thanks.
Constructing a single regular expression to validate a number is really difficult. There simply are too many criteria to consider. Perlfaq4 contains a section "How do I determine whether a scalar is a number/whole/integer/float?
The code from that documentation shows the following tests:
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\n"}
if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/) {
print "is a C float\n"
}
- The first test disqualifies an unsigned integer.
- The second test qualifies a whole number.
- The third test qualifies an integer.
- The fourth test qualifies a positive/negatively signed integer.
- The fifth test qualifies a real number.
- The sixth test qualifies a decimal number.
- The seventh test qualifies a number in c-style scientific notation.
So if you were using those tests (excluding the first one) you would have to verify that one or more of the tests passes. Then you've got a number.
Another method, since you don't want to use the module Scalar::Util, you can learn from the code IN Scalar::Util. The looks_like_number() function is set up like this:
sub looks_like_number {
local $_ = shift;
# checks from perlfaq4
return $] < 5.009002 unless defined;
return 1 if (/^[+-]?\d+$/); # is a +/- integer
return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # a C float
return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i)
or ($] >= 5.006001 and /^Inf$/i);
0;
}
You should be able to use the portions of that function that are applicable to your situation.
I would like to point out, however, that Scalar::Util
is a core Perl module; it ships with Perl, just like strict
does. The best practice of all is probably to just use it.
You should use Regexp::Common, most patterns are more complicated than you realize.
use Regexp::Common;
my $real = 3.14159;
print "Real" if $real =~ /$RE{num}{real}/;
However, the pattern is not anchored by default, so a stricter version is:
my $real_pat = $RE{num}{real};
my $real = 3.14159;
print "Real" if $real =~ /^$real_pat$/;
Well first you should make sure that the number does not contain any commas so you do this:
$var =~ s/,//g; # remove all the commas
Then create another variable to do the rest of the compare.
$var2=$var;
Then remove the . from the new variable yet only once occurrence.
$var2 =~ s/.//; # replace . with nothing to compare yet only once.
now var2 should look like an integer with no "." so do this:
if($var2 !~ /^[+-]?\d+$/){
print "not valid";
}else{
#use var1
}
you can fix this code and write it as a function if you need to use it more than once. Cheers!
精彩评论