当您在数字上下文中使用 Perl 字符串时,例如数字比较,它会识别看起来像十进制数字的起始部分并忽略之后的内容。无论它识别什么都会成为数字。
它遵循以下基本规则:
- 忽略前导空格。当您从列数据中提取一个字段并且数字不占用整个列时,这很方便。
- 允许使用单个前导符号(
+ 或 -)
- 跳过前导零(所以,没有八进制)
- 捕获十进制 ASCII 数字(0,1,2,3,4,5,6,7,8,9),允许单个小数点(因此,没有语义版本号)
- 在第一个非十进制数字字符处停止
- 到目前为止,您所拥有的就是数字。如果你什么都没有,这个数字就是 0。
不过有几点需要注意:
- 向字符串添加 0 是强制数字模式的常用方法。
- 字符串中的下划线只是下划线。您可以使用下划线分隔数字文字中的数字,但不能使用字符串分隔数字。所以,
123_456 是 123456,因为 perl 解析器处理 _,但 '123_456' 只是 123。
- 但是,如果第一个字符(不包括符号)是“Inf”,在任何情况下,字符串都会转换为“Inf”并包含
- 符号但不包含+ 符号。这是 Infinity 的特殊 IEEE 值。
- 但是,如果第一个字符(不包括符号)是“NaN”,则在任何情况下,字符串都会转换为“Nan”并排除任何一个符号。这是特殊的“非数字”值。
这里有一些例子:
#!perl
use v5.10;
use utf8;
use open qw(:std :utf8);
my @strings = qw(
-5 +7 +006 -01 00
+.1234 -.9876 .657 ..890 1.2.3
١٢٣
- + +-657
12a34 a987 123fred 0456barney
0x12 12_34 0177
NaN -NaN NAN
Inf +Inf -Inf INF Infamy Infinity
);
push @strings, " 432", "+ 123", " -987", " +063"," NaN", " Inf", '';
foreach my $string ( @strings ) {
printf "%-12s => %s\n", qq('$string'), 0 + $string;
}
然后输出:
'-5' => -5
'+7' => 7
'+006' => 6
'-01' => -1
'00' => 0
'+.1234' => 0.1234
'-.9876' => -0.9876
'.657' => 0.657
'..890' => 0
'1.2.3' => 1.2
'١٢٣' => 0
'-' => 0
'+' => 0
'+-657' => 0
'12a34' => 12
'a987' => 0
'123fred' => 123
'0456barney' => 456
'0x12' => 0
'12_34' => 12
'0177' => 177
'NaN' => NaN
'-NaN' => NaN
'NAN' => NaN
'Inf' => Inf
'+Inf' => Inf
'-Inf' => -Inf
'INF' => Inf
'Infamy' => Inf
'Infinity' => Inf
' 432' => 432
'+ 123' => 0
' -987' => -987
' +063' => 63
' NaN' => NaN
' Inf' => Inf
'' => 0
最后,关于 Perl 标量还有一个有趣的地方。当您使用字符串作为数字时,Perl 将字符串转换为数字并记住转换。但是,它不会更改字符串。 Devel::Peek 向您展示 Perl 数据结构的内部结构。
#!perl
use v5.10;
use Devel::Peek;
select(STDERR); $|++; # just to order the output from Dump
my $string = '123fred';
say "string is <$string>";
Dump( $string );
say '-' x 40;
my $n = $string + 0;
say "string is <$string>";
Dump( $string );
这是输出。首先,$string 有一个用于字符串的PV(指针值)。数值运算之后,还有IV和NV数值的数值。
string is <123fred>
SV = PV(0x7f8be980cab0) at 0x7f8bea0160f8
REFCNT = 1
FLAGS = (POK,IsCOW,pPOK)
PV = 0x7f8be9610ca0 "123fred"\0
CUR = 7
LEN = 10
COW_REFCNT = 1
----------------------------------------
string is <123fred>
SV = PVNV(0x7f8be980ac50) at 0x7f8bea0160f8
REFCNT = 1
FLAGS = (POK,IsCOW,pIOK,pNOK,pPOK)
IV = 123
NV = 123
PV = 0x7f8be9610ca0 "123fred"\0
CUR = 7
LEN = 10
COW_REFCNT = 1