簡體   English   中英

將字符串分配給Perl substr?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM