substr EXPR,OFFSET,LENGTH,REPLACEMENT
substr EXPR,OFFSET,LENGTH
substr EXPR,OFFSET

從 EXPR 中擷取子字串並傳回。第一個字元在偏移量為零處。如果 OFFSET 為負值,則從字串結尾開始往回數。如果省略 LENGTH,則傳回從頭到字串結尾的所有內容。如果 LENGTH 為負值,則從字串結尾開始往回數,並略過這麼多個字元。

my $s = "The black cat climbed the green tree";
my $color  = substr $s, 4, 5;      # black
my $middle = substr $s, 4, -11;    # black cat climbed the
my $end    = substr $s, 14;        # climbed the green tree
my $tail   = substr $s, -4;        # tree
my $z      = substr $s, -4, 2;     # tr

你可以將 substr 函數用作左值,這種情況下 EXPR 本身必須是左值。如果你指定比 LENGTH 短的內容,則字串會縮短;如果你指定比 LENGTH 長的內容,則字串會延伸以容納它。若要維持字串長度不變,你可能需要使用 sprintf 來填補或截斷你的值。

如果 OFFSET 和 LENGTH 指定的子字串部分超出字串範圍,則只會傳回字串範圍內的部份。如果子字串超出字串的任一端,substr 會傳回未定義值並產生警告。當用作左值時,指定完全超出字串範圍的子字串會引發例外。以下範例顯示邊界情況的行為

my $name = 'fred';
substr($name, 4) = 'dy';         # $name is now 'freddy'
my $null = substr $name, 6, 2;   # returns "" (no warning)
my $oops = substr $name, 7;      # returns undef, with warning
substr($name, 7) = 'gap';        # raises an exception

使用 substr 作為左值的另一種方法是將 REPLACEMENT 字串指定為第 4 個參數。這允許你替換 EXPR 的部分內容,並在一個操作中傳回之前在那裡的內容,就像你可以使用 splice 一樣。

my $s = "The black cat climbed the green tree";
my $z = substr $s, 14, 7, "jumped from";    # climbed
# $s is now "The black cat jumped from the green tree"

請注意,substr 三參數版本傳回的左值會作為「神奇子彈」;每次指定給它時,它都會記住原始字串中哪個部分正在被修改;例如

my $x = '1234';
for (substr($x,1,2)) {
    $_ = 'a';   print $x,"\n";    # prints 1a4
    $_ = 'xyz'; print $x,"\n";    # prints 1xyz4
    $x = '56789';
    $_ = 'pq';  print $x,"\n";    # prints 5pq9
}

對於負值偏移量,當目標字串被修改時,它會記住從字串結尾開始的位置

my $x = '1234';
for (substr($x, -3, 2)) {
    $_ = 'a';   print $x,"\n";    # prints 1a4, as above
    $x = 'abcdefg';
    print $_,"\n";                # prints f
}

在 Perl 版本 5.10 之前,多次使用左值所產生的結果未指定。在 5.16 之前,帶負偏移量的結果未指定。