4

我有一个数组中的文件名前缀@list1列表和第二个数组中的完整文件名列表@list2。最后,我想得到第三个数组,其中仅包含与 . 中的前缀不匹配的完整文件名@list1。我开始了:

for my $match (@list1) {
  @list3 = grep { !/$match/ } @list2;
}

但它没有做我认为它会做的事情。我有什么选择才能得到我正在寻找的结果。

4

3 回答 3

5

也许交替正则表达式会有所帮助:

use strict;
use warnings;

my @list1 = qw/a.f c data g j/;
my @list2 = qw/myfile.txt a.file.txt data.txt otherfile.txt jargon.txt/;

my $regex = join '|', map "\Q$_\E", @list1;

my @list3 = grep !/^(?:$regex)/, @list2;

print "$_\n" for @list3;

输出:

myfile.txt
otherfile.txt
于 2012-11-19T23:58:12.977 回答
1

如果您想使用更像列表表达式的方式(如您的示例中所示),您可以使用以下方法:

#!/usr/bin/env perl

use strict;
use warnings;
use List::Util 'first';
use feature 'say';

my @filenames = qw(foo bar baz quux alice bob);
my @forbidden = qw(f ba);

my @matching  = grep {
    my $filename = $_;
    not defined first { $filename =~ /^\Q$_/ } @forbidden;
} @filenames;

say for @matching;

输出:

quux
alice
bob

注意:我first在这里使用了 core- 而不是 core- grep,因为对于长@forbidden列表,它可能会更有效,因为它在第一个(并且可能只有一个)匹配后停止。

于 2012-11-20T11:21:52.490 回答
0
#!/usr/bin/perl

use strict;
use warnings;

my @prefixes = qw(a b d);
my @items = qw(apple banana cow dog fruitcake orangutan crabcake deer);

my @nonmatching;
ITEMS: foreach my $item (@items) {
    foreach my $prefix (@prefixes) {
        next ITEMS if ($item =~ /^$prefix/)
    }
    push @nonmatching, $item
}

$,=$\="\n";
print @nonmatching;

产量

cow
fruitcake
orangutan
crabcake

根据raina77ow 的建议进行编辑。

于 2012-11-19T23:03:55.993 回答