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 之前,负偏移量的结果是不确定的。