我试图按照一些示例在下面的代码中使用智能匹配,但是失败了(没有过滤掉)。如何在此处使用智能匹配来同时匹配多个正则表达式?
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;
}
}
答案 0 :(得分:3)
这里不需要智能匹配。右边有一个正则表达式,左边有一个字符串的~~也可能是a =〜,就像你拥有它一样。你想做什么?
对于你的比赛,你有两种方法可以选择。如果要将字符串用作模式,则需要使用匹配运算符:
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/*" );
答案 1 :(得分: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 /