【发布时间】:2014-12-30 19:12:33
【问题描述】:
如果我像这样使用split:
my @split = split(/\s*/, $line);
print "$split[1]\n";
与input:
cat dog
我明白了:
a
但是,如果我在 split 中使用 \s+,我会得到:
dog
我很好奇为什么它们不会产生相同的结果?另外,按字符拆分字符串的正确方法是什么?
感谢您的帮助。
【问题讨论】:
如果我像这样使用split:
my @split = split(/\s*/, $line);
print "$split[1]\n";
与input:
cat dog
我明白了:
a
但是,如果我在 split 中使用 \s+,我会得到:
dog
我很好奇为什么它们不会产生相同的结果?另外,按字符拆分字符串的正确方法是什么?
感谢您的帮助。
【问题讨论】:
\s* 实际上表示零个或多个空白字符。在cat 中的c 和a 之间是零空格,产生您所看到的结果。
对于正则表达式引擎,您的字符串如下所示:
c
zero spaces
a
zero spaces
t
multiple spaces
d
zero spaces
o
zero spaces
g
按照这个逻辑,如果你使用\s+作为分隔符,它只会匹配cat和dog之间的多个空格。
【讨论】:
* 匹配 0 次或多次。这意味着它可以匹配字符之间的空字符串。 + 匹配 1 次或多次,这意味着它必须匹配至少一个字符。
split 的文档中对此进行了描述:
如果 PATTERN 匹配空字符串,则在匹配位置(字符之间)拆分 EXPR。
另外,当你在空格上分割时,大多数时候你真的想使用文字空间:
.. split ' ', $line;
如此处所述:
作为另一种特殊情况,“split”模拟了 当 PATTERN 被省略或为 literal 时,命令行工具 awk 由单个空格字符组成的字符串(例如 ' ' 或 "\x20", 但不是例如“/ /”)。在这种情况下,EXPR 中的任何前导空格都是 在拆分发生之前删除,而 PATTERN 则被视为 如果是“/\s+/”;特别是,这意味着 any 是连续的 空格(不仅仅是单个空格字符)用作分隔符。 但是,可以通过指定 模式“/ /”而不是字符串“”,从而只允许一个 单个空格字符作为分隔符。
【讨论】:
如果要将字符串拆分为单个字符的列表,则应为 split 使用空的正则表达式模式,如下所示
my $line = 'cat';
my @split = split //, $line;
print "$_\n" for @split;
输出
c
a
t
有些人喜欢unpack,像这样
my @split = unpack '(A1)*', $line;
给出完全相同的结果。
【讨论】: