Perl比较运算符和字符串化的“数字”

时间:2012-03-30 11:16:40

标签: string perl comparison numbers operators

我最近和perl一起工作了很多,但我还不知道<,>,>=,=<, ne,gt等等...字符串化“数字”,“数字”我的意思是:'1.4.5.6.7.8 0.0'

纠正我如果我错了,以下内容将返回true:

if ('1.4.5' > '8.7.8');

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

基本上我正在尝试比较由以下形式组成的版本号:

1.3.4.0.2

我可以对每个数字进行数字比较,但在此之前,我想要知道的 字符串比较运算符对这些字符串执行。

谢谢,

5 个答案:

答案 0 :(得分: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;

答案 1 :(得分:8)

字符串比较仅在点之间的每个数字具有相同长度时才有效。字符串比较不知道 number ,并将开始比较点和数字(因为它们都是字符串中的字符)。

有一个CPAN模块可以完全满足您的要求:Sort::Versions

答案 2 :(得分:3)

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

但对于negt等,如果您的字符串由数字或其他任何内容(包括点)组成,则无关紧要。因此:

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等进行版本比较,您必须选择不同的方法,例如,在另一个答案中。

答案 3 :(得分:2)

不确定此开销,但您可以尝试Sort::Naturally。特别是ncmp运营商。

答案 4 :(得分: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