Perl - 逗号上的拆分字符串.忽略空格

A.D*_*A.D 3 regex perl whitespace split comma

我有这个字符串:

$str="     a, b,    c>d:e,  f,    g ";
Run Code Online (Sandbox Code Playgroud)

在此字符串中可能有空格和/或制表符

我在perl中拆分了字符串:

my (@COLUMNS) = split(/[\s\t,]+/, $str));
Run Code Online (Sandbox Code Playgroud)

但这会在位置[0]中创建一个领先的空间.

@COLUMNS=[

    a
    b
    c>d:e
    f
    g
]
Run Code Online (Sandbox Code Playgroud)

我要这个:

@COLUMNS=[
    a
    b
    c>d:e
    f
    g
]
Run Code Online (Sandbox Code Playgroud)

Hun*_*len 6

一个非常常见的解决方案是转换从split返回的值.在这种情况下,您要删除任何前导或尾随空格,通常称为修剪操作.使用这种方法,您不必担心拆分操作中的空格:

use strict; 
use warnings; 

my $str="     a, b,    c>d:e,  f,    g ";
my @columns = map { s/^\s*|\s*$//gr } split(/,/, $str);
print join(',', @columns), "\n";
Run Code Online (Sandbox Code Playgroud)

@toolic提到的另一个解决方案是事先删除所有空格:

use strict; 
use warnings; 

my $str="     a, b,    c>d:e,  f,    g ";
$str =~ s/\s+//g; # remove all occurrences of 1 or more spaces
my @columns = split(/,/, $str);
print join(',', @columns), "\n";
Run Code Online (Sandbox Code Playgroud)

以上两个解决方案都返回此输出:

A,B,C> d:E,F,G

有关/r修饰符的更多信息:

/r是一个修饰符,可以应用于非破坏性的替换.这意味着不修改原始字符串,而是创建,修改和返回副本.这具有优势,因为通常在标量上下文中,s///运算符将返回发生的替换次数而不是修改后的字符串.这仅适用于Perl版本> = 5.14.对于此下面的Perl版本的等效声明将是:

my $original = "some_string";
(my $copy = $original) =~ s/$search_pattern/$replace_pattern/;
Run Code Online (Sandbox Code Playgroud)

并在地图中使用:

map { 
   (my $temp = $_) =~ s/$search_pattern/$replace_pattern/; $temp 
} split /$delimiter/, $original;
Run Code Online (Sandbox Code Playgroud)

例如:

my $string = 'abc'; 
my $num_substitutions = $string =~ s/a/d/; # 1 

my $string = 'abc';
my $new_string = $string =~ s/a/d/r; # dbc
Run Code Online (Sandbox Code Playgroud)

  • 注意`r`正则表达式修饰符仅在perl> 5.14的版本中可用 (2认同)

Bor*_*din 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;
Run Code Online (Sandbox Code Playgroud)

产量

["a", "b", "c>d:e", "f", "g"]
Run Code Online (Sandbox Code Playgroud)

请注意,就像您的拆分一样,此方法将忽略任何空字段:类似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;
}
Run Code Online (Sandbox Code Playgroud)

产量

["a", "", "", "two words", "", "", "b"]
Run Code Online (Sandbox Code Playgroud)