将字符串 EXPR 分割为一个字符串列表,并在列表上下文中返回该列表,或在标量上下文中返回列表的大小。(在 Perl 5.11 之前,它还用列表覆盖了 @_
,在空和标量上下文中。如果你针对的是旧的 perl,请注意。)
如果只给出了 PATTERN,则 EXPR 默认值为 $_
。
EXPR 中与 PATTERN 匹配的任何内容都被视为分隔符,它将 EXPR 分割为子字符串(称为“字段”),不包括分隔符。请注意,分隔符的长度可能超过一个字符,甚至可能没有任何字符(空字符串,这是一个零宽匹配)。
PATTERN 不必是常量;可以使用表达式来指定在运行时变化的模式。
如果 PATTERN 匹配空字符串,则在匹配位置(字符之间)分割 EXPR。例如,以下内容
my @x = split(/b/, "abc"); # ("a", "c")
使用 'abc'
中的 b
作为分隔符来生成列表 (“a”, “c”)。但是,这是
my @x = split(//, "abc"); # ("a", "b", "c")
使用空字符串匹配作为分隔符;因此,空字符串可用于将 EXPR 分割为其组成字符的列表。
对于 split
的特殊情况,匹配运算符 语法 (//
) 中给出的空模式专门匹配空字符串,这与其通常解释为上次成功匹配相反。
如果 PATTERN 是 /^/
,则将其视为使用了 多行修饰符 (/^/m
),因为否则它没有多大用处。
/m
和任何其他对 qr
有效的模式修饰符(在 "qr/STRING/msixpodualn" in perlop 中总结)可以明确指定。
作为另一个特殊情况,split
在 PATTERN 被省略或由单个空格字符组成的字符串(例如 ' '
或 "\x20"
,但不包括 / /
)时,模拟命令行工具 awk 的默认行为。在这种情况下,在分割发生之前,EXPR 中的任何前导空格都会被删除,而 PATTERN 则被视为 /\s+/
;特别是,这意味着任何连续空格(不仅仅是单个空格字符)都用作分隔符。
my @x = split(" ", " Quick brown fox\n");
# ("Quick", "brown", "fox")
my @x = split(" ", "RED\tGREEN\tBLUE");
# ("RED", "GREEN", "BLUE")
以这种方式使用 split 与 qw//
的工作方式非常相似。
但是,可以通过指定模式 / /
而不是字符串 " "
来避免这种特殊处理,从而只允许单个空格字符作为分隔符。在早期的 Perl 中,此特殊情况仅限于将纯 " "
用作 split 的模式参数;在 Perl 5.18.0 及更高版本中,此特殊情况由计算为简单字符串 " "
的任何表达式触发。
从 Perl 5.28 开始,此特殊情况的空格分割在 "use feature 'unicode_strings'"
的范围内按预期工作。在以前的版本中,以及在该功能的范围之外,它表现出 "The "Unicode Bug"" in perlunicode:根据 Unicode 规则但不是根据 ASCII 规则为空格的字符可以被视为字段的一部分,而不是字段分隔符,具体取决于字符串的内部编码。
如果省略,PATTERN 默认为单个空格," "
,触发前面描述的awk 仿真。
如果指定了 LIMIT 并且为正,则它表示可以将 EXPR 分割为的最大字段数;换句话说,LIMIT 比 EXPR 可以分割的最大次数多 1。因此,LIMIT 值 1
意味着 EXPR 最多可以分割 0 次,最多产生一个字段(即 EXPR 的整个值)。例如
my @x = split(//, "abc", 1); # ("abc")
my @x = split(//, "abc", 2); # ("a", "bc")
my @x = split(//, "abc", 3); # ("a", "b", "c")
my @x = split(//, "abc", 4); # ("a", "b", "c")
如果 LIMIT 为负数,则将其视为任意大值;尽可能多地生成字段。
如果省略 LIMIT(或等于零),则通常将其视为负数,但例外情况是剥离尾部空字段(始终保留头部空字段);如果所有字段都为空,则所有字段都被视为尾部字段(在这种情况下,将被剥离)。因此,以下
my @x = split(/,/, "a,b,c,,,"); # ("a", "b", "c")
仅生成一个三元素列表。
my @x = split(/,/, "a,b,c,,,", -1); # ("a", "b", "c", "", "", "")
生成一个六元素列表。
在时间关键型应用程序中,值得避免拆分为比必要更多的字段。因此,当分配给列表时,如果省略 LIMIT(或为零),则将 LIMIT 视为比列表中的变量数大 1;对于以下内容,LIMIT 隐式为 3
my ($login, $passwd) = split(/:/);
请注意,拆分计算结果为空字符串的 EXPR 始终生成零个字段,无论指定的 LIMIT 如何。
当在 EXPR 的开头处有正宽匹配时,将生成一个头部空字段。例如
my @x = split(/ /, " abc"); # ("", "abc")
拆分为两个元素。但是,EXPR 开头的零宽匹配永远不会生成空字段,因此
my @x = split(//, " abc"); # (" ", "a", "b", "c")
拆分为四个元素,而不是五个元素。
另一方面,当在 EXPR 的末尾处有匹配时,将生成一个尾部空字段,无论匹配的长度如何(当然,除非明确给出了非零 LIMIT,否则将删除此类字段,如最后一个示例所示)。因此
my @x = split(//, " abc", -1); # (" ", "a", "b", "c", "")
如果 PATTERN 包含捕获组,则对于每个分隔符,将为每个由组捕获的子字符串生成一个附加字段(按照组指定的顺序,如反向引用);如果任何组不匹配,则它将捕获undef
值,而不是子字符串。此外,请注意,每当有分隔符(即每当发生拆分)时,都会生成任何此类附加字段,并且此类附加字段不计入 LIMIT。考虑在列表上下文中计算的以下表达式(每个返回的列表在关联的注释中提供)
my @x = split(/-|,/ , "1-10,20", 3);
# ("1", "10", "20")
my @x = split(/(-|,)/ , "1-10,20", 3);
# ("1", "-", "10", ",", "20")
my @x = split(/-|(,)/ , "1-10,20", 3);
# ("1", undef, "10", ",", "20")
my @x = split(/(-)|,/ , "1-10,20", 3);
# ("1", "-", "10", undef, "20")
my @x = split(/(-)|(,)/, "1-10,20", 3);
# ("1", "-", undef, "10", undef, ",", "20")