我建议您使用全局正则表达式匹配,查找所有既不是逗号也不是空格的字符子序列。这将产生与您的
split(/[\s\t,]+/
相同的输出。(请注意,
\t
是多余的,因为
\s
也可以匹配制表符)。但是,将创建一个没有任何空元素的列表。
use strict;
use warnings 'all';
my $str = " a, b, c>d:e, f, g ";
my @columns = $str =~ /[^\s,]+/g;
use Data::Dump;
dd \@columns;
输出
["a", "b", "c>d:e", "f", "g"]
请注意,与您的分割方法一样,此方法将忽略任何空字段:例如
a,,,b
将返回
[ 'a', 'b' ]
而不是
[ 'a', '', '', 'b' ]
。同时,包含空格的列也会被拆分,因此
a,two words,b
将生成
[ 'a', 'two', 'words', 'b' ]
而不是
[ 'a', 'two words', 'b' ]
。只有您能告诉这些情况是否可能出现。
如果有任何可能导致此方法产生错误结果的情况,则最好只在逗号上进行拆分,并编写一个子例程来修整生成的字段。
use strict;
use warnings 'all';
sub trim(;$);
my $str=" a ,, ,two words ,,, b";
my @columns = map trim, split /,/, $str;
use Data::Dump;
dd \@columns;
sub trim(;$) {
(my $trimmed = $_[0] // $_) =~ s/\A\s+|\s+\z//g;
$trimmed;
}
输出
["a", "", "", "two words", "", "", "b"]
\t
,因为\s
已经包括了空格和制表符(以及其他任何_空白字符_,尽管我不知道其他的是什么)。 - PerlDuck\s
匹配的ASCII字符的Unicode名称包括CHARACTER TABULATION
、LINE FEED
、LINE TABULATION
、FORM FEED
、CARRIAGE RETURN
和SPACE
,即[\t\n\x0B\f\r ]
。还有十几个ASCII之外的字符也符合匹配条件。 - Borodin