1

他の人が書いた Perl スクリプトを調べていると、次のことがわかりました。

$num2 = '000000';
substr($num2, length($num2)-length($num), length($num)) = $num;
my $id_string = $text."_".$num2

無知で申し訳ありませんが、訓練を受けていない Perl プログラマーにとっては、2 行目は作成者が$num関数の結果に文字列を代入しているように見えますsubstr。この行は正確に何をしますか?

4

4 に答える 4

6

まさにあなたがそれがするだろうと思うこと:

$ perldoc -f substr

substr() 関数を左辺値として使用できます。この場合、EXPR 自体が左辺値でなければなりません。LENGTH よりも短いものを割り当てると、文字列は縮小し、LENGTH よりも長いものを割り当てると、それに合わせて文字列が大きくなります。文字列を同じ長さに保つには、「sprintf」を使用して値をパディングまたはチョップする必要がある場合があります。

于 2012-09-10T19:52:24.897 に答える
4

Perl では (Python とは異なり、文字列、タプルはその場で変更できません)、文字列はその場で変更できます。それがsubstrここで行っていることであり、文字列の一部のみを変更しています。この構文の代わりに、より不可解な構文を使用できます。

substr($num2, length($num2)-length($num), length($num),$num);

これは同じことを達成します。さらに伸ばすことができます。文字列内のfooのすべてのインスタンスをbarで置き換えたいと想像してください。ただし、最初の 50 文字内のみです。Perl では、ワンライナーでそれを行うことができます。

substr($target,0,50) =~ s/foo/bar/g;

いいですね。

于 2012-09-10T19:58:30.277 に答える
2

「正確に」、あなたは尋ねますか?

通常、substr退屈な文字列 (PV with POK) を返します。

$ 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左辺値 (割り当て可能な値) が期待される場所で が評価されると、魔法のスカラー (PVLV と GMG (魔法の取得) および 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) が最後に繰り返されていることがわかります (下部に表示される 0x8948c18 の SV)。

この魔法のスカラーを読み取ると、代わりに関連する関数が呼び出されます。同様に、書き込みは関連する別の関数を呼び出します。これらの関数は、渡された文字列の選択された部分をsubstr読み取ったり変更したりします。

perl -E'
   $_ = "abcde";
   my $ref = \substr($_, 1, 3);  # $$ref is magical
   say $$ref;                    # bcd
   $$ref = '123';
   say $_;                       # a123e
'
于 2012-09-10T22:00:53.630 に答える
1

「0」で埋められた数値を取得するために、$ num2の最後の長さ($ num)文字を$numの内容で上書きしているように見えます。

私はほとんどの人がsprintf()でこれと同じタスクを達成すると思います

于 2012-09-10T19:55:51.180 に答える