我有这个字符串:
$str=" a, b, c>d:e, f, g ";
在此字符串中可能有空格和/或标签
我在perl中分割字符串:
my (@COLUMNS) = split(/[\s\t,]+/, $str));
但是这会在位置[0]中创建一个前导空格。
@COLUMNS=[
a
b
c>d:e
f
g
]
我想要这个:
@COLUMNS=[
a
b
c>d:e
f
g
]
答案 0 :(得分:6)
一个非常常见的解决方案是转换从split返回的值。在这种情况下,您要删除任何前导或尾随空格,通常称为 trim 操作。使用这种方法,您不必担心拆分操作中的空格:
s///
@toolic提及的另一个解决方案是事先删除所有空格:
my $original = "some_string";
(my $copy = $original) =~ s/$search_pattern/$replace_pattern/;
以上两种解决方案都会返回此输出:
A,B,c取代; d:E,F,G
有关/r
修饰符的更多信息:
map {
(my $temp = $_) =~ s/$search_pattern/$replace_pattern/; $temp
} split /$delimiter/, $original;
是一个修饰符,可以应用于非破坏性的替换。这意味着不修改原始字符串,而是创建,修改和返回副本。这具有优势,因为通常在标量上下文中,my $string = 'abc';
my $num_substitutions = $string =~ s/a/d/; # 1
my $string = 'abc';
my $new_string = $string =~ s/a/d/r; # dbc
运算符将返回发生的替换数而不是修改后的字符串。这仅适用于Perl版本> = 5.14。下面的Perl版本的等效声明将是:
{{1}}
并在地图中使用:
{{1}}
例如:
{{1}}
答案 1 :(得分:6)
我建议您使用全局正则表达式匹配来查找既不是逗号也不是空格的字符的所有子序列
它将产生与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' ]
而非{ {1}}。此外,包含空格的列将被拆分,因此[ '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;
}