![](/img/trans.png)
[英]Perl substr(STRING, @ARRAY) ne substr(STRING, OFFSET, LENGTH)?
[英]Assigning a string to Perl substr?
我正在查看别人编写的Perl脚本,发现了这一点:
$num2 = '000000';
substr($num2, length($num2)-length($num), length($num)) = $num;
my $id_string = $text."_".$num2
原谅我的无知,但是对于未经培训的Perl程序员,第二行看起来好像作者正在将字符串$num
分配给函数substr
的结果。 这条线到底是做什么的?
正是您认为的那样:
$ perldoc -f substr
您可以将substr()函数用作左值,在这种情况下,EXPR本身必须是左值。 如果分配的长度短于LENGTH,则字符串将缩小;如果分配的长度大于LENGTH,则字符串将增长以容纳它。 为了使字符串长度相同,您可能需要使用“ sprintf”填充或截取值。
在Perl中(不同于Python,字符串,元组不能就地修改),可以在原位修改字符串。 这就是substr
在这里所做的,它仅修改字符串的一部分。 除了这种语法,您还可以使用更隐秘的语法:
substr($num2, length($num2)-length($num), length($num),$num);
完成相同的事情。 您可以进一步拉伸它。 假设您想用字符串中的bar替换foo的所有实例,但只能在前50个字符之内。 Perl将让您一站式完成:
substr($target,0,50) =~ s/foo/bar/g;
很好,不是吗?
“是的”,您问?
通常, 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(获取魔法)和SMG(设置魔法)的PVLV)。
$ 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
'
在我看来,它用$ num的内容覆盖$ num2的最后一个length($ num)个字符,以便获得一个“ 0”填充数字。
我想大多数人都会用sprintf()完成相同的任务
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.