我正在看别人写的Perl脚本,我发现了这个:
$num2 = '000000';
substr($num2, length($num2)-length($num), length($num)) = $num;
my $id_string = $text."_".$num2
请原谅我无知,但对于未经训练的Perl程序员,第二行看起来好像作者正在将字符串$num
分配给函数substr
的结果。这条线究竟做了什么?
答案 0 :(得分:6)
你认为它会做什么:
$ perldoc -f substr
在这种情况下,您可以将substr()函数用作左值 EXPR本身必须是左值。如果你指定更短的东西 比LENGTH,字符串将缩小,如果你指定 比LENGTH更长的东西,字符串将增长到 容纳它。为了保持字符串长度相同,您可以 需要使用“sprintf”来填充或削减你的价值。
答案 1 :(得分:4)
在Perl中,(不像Python,其中字符串,元组不能就地修改),字符串可以在原位修改。这就是substr
在这里做的事情,它只修改字符串的一部分。您可以使用更加神秘的语法代替此语法:
substr($num2, length($num2)-length($num), length($num),$num);
完成同样的事情。你可以进一步拉伸它。想象一下,您想要在字符串中用 bar 替换 foo 的所有实例,但只能在前50个字符中。 Perl会让你在单行中完成它:
substr($target,0,50) =~ s/foo/bar/g;
很好,不是吗?
答案 2 :(得分:2)
“完全”,你问?
通常,substr
会返回一个无聊的字符串(带有POK的PV)。
$ perl -MDevel::Peek -e'$_="abcd"; Dump("".substr($_, 1, 2));'
SV = PV(0x99f2828) at 0x9a0de38
REFCNT = 1
FLAGS = (PADTMP,POK,pPOK)
PV = 0x9a12510 "bc"\0
CUR = 2
LEN = 12
然而,当substr
被评估为期望左值(可赋值)时,它会返回一个神奇的标量(带有GMG的PVLV(获得魔法)和SMG(设置魔法))。
$ perl -MDevel::Peek -e'$_="abcd"; Dump(substr($_, 1, 2));'
SV = PVLV(0x8941b90) at 0x891f7d0
REFCNT = 1
FLAGS = (TEMP,GMG,SMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x8944900
MG_VIRTUAL = &PL_vtbl_substr
MG_TYPE = PERL_MAGIC_substr(x)
TYPE = x
TARGOFF = 1
TARGLEN = 2
TARG = 0x8948c18
FLAGS = 0
SV = PV(0x891d798) at 0x8948c18
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0x89340e0 "abcd"\0
CUR = 4
LEN = 12
这个神奇的标量包含传递给susbtr
(TARG,TARGOFF和TARGLEN)的参数。您可以看到最后重复的TARG
(原始标量传递给substr
)指向的标量(您在底部看到的SV位于0x8948c18处)。
任何对这个神奇标量的读取都会导致相关的函数被调用。类似地,写调用不同的相关函数。这些函数会导致传递给substr
的字符串的选定部分被读取或修改。
perl -E'
$_ = "abcde";
my $ref = \substr($_, 1, 3); # $$ref is magical
say $$ref; # bcd
$$ref = '123';
say $_; # a123e
'
答案 3 :(得分:1)
在我看来,它是用$ num的内容覆盖$ num2的最后一个长度($ num)字符,以便得到一个'0'填充数字。
我想大多数人都会用sprintf()
完成同样的任务