我知道有一个库可以做到这一点
使用Scalar :: Util qw(looks_like_number);
但是我想用perl正则表达式来做。我希望它能用于双数而不仅仅是整数。
所以我想要比这更好的东西
$ var =〜/ ^ [+ - ]?\ d + $ /
感谢。
答案 0 :(得分:15)
构造单个正则表达式来验证数字真的很难。只有太多的标准需要考虑。 Perlfaq4包含一节“我如何确定标量是否为数字/整数/整数/浮点数?
该文档中的代码显示以下测试:
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"
}
因此,如果您使用这些测试(不包括第一个测试),则必须验证一个或多个测试是否通过。然后你有一个号码。
另一种方法,因为您不想使用Scalar :: Util模块,您可以从代码IN Scalar :: Util中学习。 Looks_like_number()函数设置如下:
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;
}
您应该能够使用适合您情况的该功能部分。
但是,我想指出Scalar::Util
是核心Perl模块;它与Perl一起提供,就像strict
一样。所有人的最佳做法可能只是使用它。
答案 1 :(得分:6)
你应该使用Regexp :: Common,大多数模式比你意识到的要复杂。
use Regexp::Common;
my $real = 3.14159;
print "Real" if $real =~ /$RE{num}{real}/;
但是,默认情况下不会锚定模式,因此更严格的版本是:
my $real_pat = $RE{num}{real};
my $real = 3.14159;
print "Real" if $real =~ /^$real_pat$/;
答案 2 :(得分:0)
首先,您应确保该号码不包含任何逗号,以便您执行此操作:
$ var = ~s /,// g; #删除所有逗号
然后创建另一个变量来完成比较的其余部分。
$ VAR2 = $变种;
然后删除。来自新变量但只出现一次。
$ var2 = ~s /.//; #replace。没有什么比较,只有一次。
现在var2应该看起来像一个没有“。”的整数。 这样做:
if($var2 !~ /^[+-]?\d+$/){
print "not valid";
}else{
#use var1
}
如果您需要多次使用它,可以修复此代码并将其编写为函数。 干杯!