我知道有一个库,做到这一点如何在perl中验证数字?
使用标量::的Util QW(looks_like_number);
但我想用perl正则表达式来做。而且我希望它能够用于双数而不仅仅是整数。
所以我想要的东西比这个
是$ var更好=〜/^[+ - ] \ d + $/
感谢?
我知道有一个库,做到这一点如何在perl中验证数字?
使用标量::的Util QW(looks_like_number);
但我想用perl正则表达式来做。而且我希望它能够用于双数而不仅仅是整数。
所以我想要的东西比这个
是$ var更好=〜/^[+ - ] \ d + $/
感谢?
构造一个正则表达式来验证一个数字是非常困难的。只有太多标准需要考虑。 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
一样。所有的最佳实践可能只是使用它。
您输入的函数在输入中不同于输入'looks_like_number('0'但'true')'! – ikegami 2011-05-11 19:29:34
...和超载对象。重载的对象在最新版本的Scalar :: Util :: PP中处理。 PP版本不再存在于发行版的最新发行版中。 – ikegami 2011-05-11 19:35:21
是的,Scalar-List-Utils-1.23有一个纯Perl版本,而Scalar-List-Utils-1.23_03没有。读者可以轻松地在CPAN上查找v1.23的源代码,因为该版本处理重载的对象。然而,我完全相信这个对话重申了这样的观点:当Scalar :: Util的looks_like_number()已经存在时,尝试用正则表达式构建一个新的通用数字合格解决方案是愚蠢的;几乎肯定会变得更加健壮,更现代化,更易于维护。另外,它是标准Perl发行版的一部分。 – DavidO 2011-05-11 19:47:31
您应该使用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$/;
不幸的是,Regexp :: Common传递了普通人可能认为有效的数字语法的东西,例如:'1..2','-1.0.2'和'1.-2'。另一个支持Scalar :: Util方法是最好的方法的例子。 – DavidO 2011-05-11 20:56:10
@DavidO该文档指出该匹配未被锚定。那些模式如果锚定在那里,则不匹配实际的数字。如果没有锚定,它们会匹配。 – 2012-07-31 02:43:00
也许这是合理的编辑您的帖子,以保持更强大的正则表达式:'m/^ $ RE {num} {real} $ /'。我还没有测试过是否会拒绝“'1.-2”“。顺便说一句:我做了++你的答案。 – DavidO 2012-07-31 02:47:00
那么首先你应该确保该号码不包含任何逗号所以你这样做:
$ var =〜s /,// g; #删除所有逗号
然后创建另一个变量来完成比较的其余部分。
$ var2 = $ var;
然后删除。从新变量中只有一次出现。
$ var2 =〜s /.//; #替换。没有什么比较,但只有一次。
现在var2应该看起来像一个没有“。”的整数。 这样做:
if($var2 !~ /^[+-]?\d+$/){
print "not valid";
}else{
#use var1
}
就可以解决这个问题的代码,如果你需要使用它不止一次把它写成一个函数。 干杯!
你知道,数字可以有一个可选部分(....)?组成部分后。至少,你已经尝试了一下。 – Ingo 2011-05-11 14:21:25
我尝试了一个我放在我的问题上,它检查一个数字(3.5)作为例子时不起作用。 – 2011-05-11 14:29:34
它是DID的工作 - 它告诉你正确,你的模式不匹配整个字符串“3.5” – Ingo 2011-05-11 14:32:09