![](/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.