2012-03-30 65 views
9

我一直在最近与perl工作很多,但我真的不知道如何<,>,>=,=<, ne,gt,等..字符串“数字”,“数字”我的意思是:'1.4 .5.6.7.8.0'Perl比较运算符和字符串化的“数字”

纠正我,如果我错了,下面的返回true:

if ('1.4.5' > '8.7.8'); 

,因为两者都将被强制为真(不是空字符串)。 但是,ne,gt等字符串运算符如何处理这些数字?

基本上我想比较的版本号包括以下形式:

1.3.4.0.2 

我可以让每个数位的数值比较,但在此之前,我ranther想知道 字符串比较运营商执行这样的字符串。

感谢,

+1

“1.4.5.6.7.8.0”不是数字。参见[perldata](http://perldoc.perl.org/perldata.html)和[Scalar :: Util](http://search.cpan.org/perldoc?Scalar::Util)的'looks_like_number'。 – ikegami 2012-03-30 19:48:31

+0

我说“数字” – snoofkin 2012-03-30 21:34:39

+1

其实,你说的“数字”:«按“数字”我的意思是:'1.4.5.6.7.8.0'»。然后你用«'>'»,每边都带*号*,所以即使你说“数字”,我的评论也是适当的。 – ikegami 2012-03-30 21:58:21

回答

17

首先:请use warnings所有的时间。你会意识到以下一次:

$ perl -wle 'print 1 unless "1.4.5" > "8.7.8"' 
Argument "8.7.8" isn't numeric in numeric gt (>) at -e line 1. 
Argument "1.4.5" isn't numeric in numeric gt (>) at -e line 1. 

的Perl v5.9.0带着version分布。并且该模块使得它非常容易比较的版本号:

use warnings; 
use version; 

my ($small, $large) = (version->parse('1.4.5'), version->parse('8.7.8')); 

print "larger\n" if $small > $large; 
print "smaller\n" if $small < $large; 
8

字符串比较将只在点与点之间的每个数字具有相同的长度工作。字符串比较不知道号码,并且将开始比较点和数字(因为它们都是字符串中的两个字符)。

那里正是你正在寻找一个不CPAN模块:Sort::Versions

3

当你使用数值关系运算符<>等比较字符串,Perl中发出警告,如果你use warnings。但是,Perl仍然会尝试将字符串转换为数字。如果字符串以数字开始,Perl将使用这些字符串,否则字符串等于0.在您的示例中,比较'1.4.5'和'8.7.8'与比较数字1.4和8.7具有相同的效果。

但是对于ne,gt等,如果您的字符串包含数字或其他任何内容(包括点),那么它并不重要。因此:

print "greater" if '2.3.4' gt '10.1.2' # prints 'greater' because '2' > '1' stringwise 
print "greater" if '02.3.4' gt '10.1.2' # prints nothing because '0' < '1' stringwise 

因此,你不能使用既不><等也不gtlt等进行版本比较,你必须选择不同的方法,如在其他答案提出的,例如。

2

由于@tent指出,@ SebastianStumpf的解决方案是接近,但并不完全正确,因为:

>perl -Mversion -e 'my @n = ("1.10", "1.9"); print "$n[0] is " . (version->parse($n[0]) > version->parse($n[1]) ? "larger" : "smaller") . " than $n[1]\n";' 
1.10 is smaller than 1.9 

幸运的是,这是很容易解决了version's documentation提示如下:

领先的“V '现在强烈建议清晰起见,并且如果省略,将在未来的版本中发出警告 。

>perl -Mversion -e 'my @n = ("1.10", "1.9"); print "$n[0] is " . (version->parse("v$n[0]") > version->parse("v$n[1]") ? "larger" : "smaller") . " than $n[1]\n";' 
1.10 is larger than 1.9