2

我试图按照一些示例在以下代码中使用智能匹配,但失败了(没有过滤掉任何内容)。如何在此处使用智能匹配一次匹配多个正则表达式?

my $regexes_to_filter_a = ("tmp", "temp", "del")
my @organism_dirs = (); # this will hold final list of dirs to processs

my @subdirs = File::Find::Rule->directory->maxdepth(1)->in($root_dir);
foreach my $subdir (@subdirs) {
    my $filter = 0;

    # IMPROVE: can do smart matching here
    foreach my $regex ( @{$regexes_to_filter_a} ) {
        if ( basename($subdir) =~ $regex ) {
            $filter = 1; # filter out this dir
            last;
        }
    }

    unless ($filter) {
        push @organism_dirs, $subdir;
    }
}
4

2 回答 2

3

您在这里不需要智能匹配。~~ 右侧有一个正则表达式,左侧有一个字符串,就像你拥有它一样,也可能是 =~。你想做什么?

对于你的比赛,你有两条路可以走。如果要将字符串用作模式,则需要使用匹配运算符:

 basename($subdir) =~ m/$regex/

如果您不想像现在一样使用匹配运算符,则需要一个正则表达式对象:

 my $regexes_to_filter_a = (qr/tmp/, qr/temp/, qr/del/);

我想你可以一次匹配所有的正则表达式。请注意,如果要将 maxdepth 设置为 1,则实际上不需要 File::Find::Rule。如果您不打算遍历目录结构,请不要使用旨在遍历目录结构的模块:

my $regexes_to_filter_a = (qr/tmp/, qr/temp/, qr/del/);
my @organism_dirs = ();

foreach my $subdir ( glob( '*' ) ) {
    next unless -d $subdir;
    unless (basename($subdir) ~~ @regexes_to_filter_a) {
        push @organism_dirs, $subdir;
            } 
        }

我认为所有这些工作都太多了。如果要排除已知的静态目录名称(因此,不是模式),只需使用哈希:

my %ignore = map { $_, 1 } qw( tmp temp del );

my @organism_dirs = 
    grep { ! exists $ignore{ basename($_) } } 
    glob( "$rootdir/*" );

如果你真的想使用智能匹配:

my %ignore = map { $_, 1 } qw( tmp temp del );

my @organism_dirs = 
    grep { basename($_) ~~ %ignore } 
    glob( "$rootdir/*" );
于 2010-09-16T07:39:20.997 回答
2

这是对您的示例的快速未经测试的更改:

my @regexes_to_filter_a = (qr/^tmp$/, qr/^temp/, qr/del/);
my @organism_dirs = (); # this will hold final list of dirs to processs

my @subdirs = File::Find::Rule->directory->maxdepth(1)->in($root_dir);
foreach my $subdir (@subdirs) {

    unless (basename($subdir) ~~ @regexes_to_filter_a) {
        push @organism_dirs, $subdir;
    }
}

主要变化是:

i) 应该是@array = (...list...);或者$array_ref = [...list...];

my @regexes_to_filter_a = ("tmp", "temp", "del");

ii) 并改为使用smart match。下面检查basename($subdir)是否在 ( ~~)@regexes_to_filter_a数组中。因此无需遍历数组并进行单独的正则表达式检查。

unless (basename($subdir) ~~ @regexes_to_filter_a) { ... }

/I3az/

于 2010-09-16T07:37:35.917 回答