split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/
split

将字符串 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")