如何将Perl split命令与空白修剪结合起来?

时间:2009-08-11 17:08:18

标签: perl split

Repost from Perlmonks同事:

我编写了一个perl脚本来分隔由分号分隔的长电子邮件列表。我想用代码做的是将分割与白色空间的修剪相结合,所以我不需要两个数组。加载第一个数组时是否需要修剪。输出是一个排序的名称列表。 感谢。

#!/pw/prod/svr4/bin/perl
use warnings;
use strict;

my $file_data =
  'Builder, Bob  ;Stein, Franklin MSW; Boop, Elizabeth PHD   Cc: Bear,
+ Izzy';
my @email_list;

$file_data =~ s/CC:/;/ig;
$file_data =~ s/PHD//ig;
$file_data =~ s/MSW//ig;

my @tmp_data = split( /;/, $file_data );

foreach my $entry (@tmp_data) {
    $entry =~ s/^[ \t]+|[ \t]+$//g;
    push( @email_list, $entry );
}

foreach my $name ( sort(@email_list) ) {
    print "$name \n";
}

7 个答案:

答案 0 :(得分:11)

如果你不需要修剪第一个和最后一个元素,这将解决问题:

@email_list = split /\s*;\s*/, $file_data;

如果您确实需要修剪第一个和最后一个元素,请首先修剪$file_data,然后重复上述操作。 :-P

答案 1 :(得分:11)

您不必使用相同的功能一次完成两个操作。有时单独执行操作可能更清楚。也就是说,首先拆分,然后从每个元素中删除空格(然后对结果进行排序):

@email_list =
    sort(
        map {
                s/\s*(\S+)\s*/\1/; $_
            }
            split ';', $file_data
    );

编辑:同时剥离一个以上字符串的一部分可能会导致陷阱,例如:思南的观点是关于在“伊丽莎白”部分留下尾随空格。我编写了该代码片段,假设名称不会有内部空格,这实际上是非常错误的,如果我有意识地注意到它,它会突出显示不正确。下面的代码得到了很大改进(也更具可读性):

@email_list =
    sort(
        map {   
                s/^\s+//;  # strip leading spaces
                s/\s+$//;  # strip trailing spaces
                $_         # return the modified string
            }
            split ';', $file_data
    );

答案 2 :(得分:2)

好吧,你可以做克里斯建议的,但它不处理$ file_data中的前导和尾随空格。

您可以像这样添加处理:

$file_data =~ s/\A\s+|\s+\z//g;

另外,请注意不需要使用第二个阵列。检查一下:

my $file_data = 'Builder, Bob  ;Stein, Franklin MSW; Boop, Elizabeth PHD   Cc: Bear, Izzy';
my @email_list;

$file_data =~ s/CC:/;/ig;
$file_data =~ s/PHD//ig;
$file_data =~ s/MSW//ig;

my @tmp_data = split( /;/, $file_data );

foreach my $entry (@tmp_data) {
    $entry =~ s/^[ \t]+|[ \t]+$//g;
}

foreach my $name ( sort(@tmp_data) ) {
    print "$name \n";
}

答案 3 :(得分:1)

my @email_list = map { s/^[ \t]+|[ \t]+$//g; $_ } split /;/, $file_data;

或更优雅:

use Algorithm::Loops "Filter";
my @email_list = Filter { s/^[ \t]+|[ \t]+$//g } split /;/, $file_data;

答案 4 :(得分:1)

请参阅常见问题解答中的How do I strip blank space from the beginning/end of a string?

@email_list = sort map {
    s/^\s+//; s/\s+$//; $_
} split ';', $file_data;

现在,请注意for循环别名数组的每个元素,所以

@email_list = sort split ';', $file_data;

for (@email_list) {
    s/^\s+//;
    s/\s+$//;
}

也可以。

答案 5 :(得分:0)

轮到我了:

my @fields = grep { $_ } split m/\s*(?:;|^|$)\s*/, $record;

它也会剥离第一个和最后一个元素。如果grep因摆脱第一个元素而过度杀伤:

my ( undef, @fields ) = split m/\s*(?:;|^|$)\s*/, $record;
如果知道有空格,

有效,但这不太可能,所以

my @fields = split m/\s*(?:;|^|$)\s*/, $record;
shift @fields unless $fields[0];

是最有把握的方式。

答案 6 :(得分:-1)

除非出现一些轻微的语法错误,否则这应该为您完成整个工作。哦,列出操作,你是多么美丽!

print join (" \n", sort { $a <=> $b } map { s/^[ \t]+|[ \t]+$//g } split (/;/, $file_data));