如何在Perl中将字符串转换为数字?

99

我有一个字符串,其中保存了一个十进制值,我需要将该字符串转换为浮点变量。所以我手头的字符串示例是"5.45",我想要一个浮点型等价物,以便我可以添加0.1。我在互联网上搜索过,但我只看到如何将字符串转换为整数。


这个问题需要进一步的细节。字符串只由数字组成吗?是字母数字混合的吗?如果字母被剥离了,那么可以吗?生成的数字有特定的目的吗? - JGurtz
9个回答

97

您根本不需要转换它:

% perl -e 'print "5.45" + 0.1;'
5.55

15
@OrangeDog的原始问题(此答案发布几个月后)已经进行了编辑 - 实际上,原始问题中涉及到浮点数。 - Alnitak
1
当字符串中有逗号时,比较该怎么办? - Ramy
[rabdelaz@Linux_Desktop:~/workspace/akatest_5]$perl -e 'print "nope\n" unless "1,000" > 10;' nope [rabdelaz@Linux_Desktop:~/workspace/akatest_5]$perl -e 'print "nope\n" if "1,000" > 10;' - Ramy

79

这是一个简单的解决方案:

示例 1

my $var1 = "123abc";
print $var1 + 0;

结果

123

示例 2

my $var2 = "abc123";
print $var2 + 0;

结果

0

9
据我所知,这是对所问问题唯一的答案。 - Cougar
4
当给一个字符串加上零时要小心。如果该字符串以"inf"或"nan"开头,则其值将不为零。 例如: my $var2 = "info123"; print $var2 + 0; 结果将是:Inf - Rodrigo De Almeida Siqueira
我正在执行一个 foreach my $i ('00'..'15') 并需要在某些地方删除前导零。这个 0+ 强制转换为数字也可以实现这一点。 - stevesliva
显然,这个方法不能用于十六进制字符串:'0x14C' + 0 的结果为0(啊啊啊) - KevinHJ

44

Perl是一种基于上下文的语言。它不是根据你提供的数据来工作的。相反,它会根据你所使用的运算符和使用它们的上下文来确定如何处理数据。如果你处理数字类型的内容,你将得到数字:

# numeric addition with strings:
my $sum = '5.45' + '0.01'; # 5.46

如果你进行字符串排序等操作,你会得到字符串:

# string replication with numbers:
my $string = ( 45/2 ) x 4; # "22.522.522.522.5"

Perl通常会自己想出应该做什么并且大多数情况下都是正确的。另一种说法是,Perl更关注动词而不是名词。

您正在尝试做某事但它没有起作用吗?


1
请原谅我在这方面的知识不足,但我不太理解你的第二个例子。您正在除以两个数字,然后将它们相乘,这如何/为什么会导致一个字符串? - gideon
4
我不是在做数学乘法运算。x 是字符串复制操作符。 - brian d foy
3
在这种情况下,应该是使用45而不是44,“22.522.522.5”中的小数点和数字0.5的来源就可以理解了。 - Vickster

10

在搜索了phill提出的同样问题(浮点数排序)后,我被谷歌带到了这里,所以我认为即使这个主题有点老,发表答案仍然是值得的。我对Perl还很陌生,但brian d foy的声明“Perl关心动词比名词更多”确实命中要害。在应用排序之前,您不需要将字符串转换为浮点数。你需要告诉排序将值作为数字而不是字符串进行排序。

my @foo = ('1.2', '3.4', '2.1', '4.6');
my @foo_sort = sort {$a <=> $b} @foo;

请参考http://perldoc.perl.org/functions/sort.html以了解更多sort的详细信息。


9
据我理解,int()函数并非用于指定数据类型的“强制转换”函数,而是被(滥)用于将上下文定义为算术上下文。我过去曾(滥)用(0+$val)确保$val被视为数字。

是的,int() 被“(滥)用”了;我明白了。 - Sapphire_Brick

7
$var += 0

可能这是你想要的。不过请注意,如果$var是字符串而无法转换为数字,你将会收到错误提示,并且$var将被重置为0

my $var = 'abc123';
print "var = $var\n";
$var += 0;
print "var = $var\n";

日志

var = abc123
Argument "abc123" isn't numeric in addition (+) at test.pl line 7.
var = 0

5

Perl实际上只有三种类型:标量、数组和哈希。即使这个区分也是有争议的。每个变量的处理方式取决于你对它的操作:

% perl -e "print 5.4 . 3.4;"
5.43.4


% perl -e "print '5.4' + '3.4';"
8.8

6
Perl有比这更多的类型,但对于单个值而言,它只是一个单一的值。 - brian d foy

1
Perl是弱类型和基于上下文的。许多标量可以根据您使用的运算符同时被视为字符串和数字。 $a = 7*6; $b = 7x6; print "$a $b\n";
您将得到42 777777
然而,有一个微妙的区别。当您从文本文件读取数字数据并将其存储在数据结构中,然后使用Data::Dumper查看它时,您会注意到您的数字被引用了。Perl在内部将它们作为字符串处理。
读取:$my_hash{$1} = $2 if /(.+)=(.+)\n/;
转储:'foo' => '42' 如果您希望在转储中获得不带引号的数字:
读取:$my_hash{$1} = $2+0 if /(.+)=(.+)\n/;
转储:'foo' => 42 在执行$2+0后,Perl注意到您已将$2视为数字,因为您使用了数字运算符。
我在尝试使用Data::Dumper比较两个哈希表时注意到了这一点。

1
在比较中,一个标量是数字还是字符串会有所不同。而且它并不总是可判断的。我可以报告一个情况,在这种情况下Perl以“科学”表示法检索了一个浮点数,并在几行代码后将其用于比较。
use strict;
....
next unless $line =~ /and your result is:\s*(.*)/;
my $val = $1;
if ($val < 0.001) {
   print "this is small\n";
}

这里的$val没有被解释为数字,例如从$line检索到的"2e-77"。添加0(或对于老式C程序员来说是0.0)有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接