2010-09-16 100 views
2

我试图遵循一些例子在下面的一段代码中使用智能匹配,但失败了(没有被过滤掉)。我如何在这里使用智能匹配来同时匹配多个正则表达式?如何使用Perl的智能匹配一次匹配多个模式?

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

的可能重复[如何在Perl中匹配多个正则表达式?](http://stackoverflow.com/questions/3694322/how-to-match-against-multiple-regexes-in-perl) – 2010-09-16 07:47:50

回答

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; 
    } 
} 

的主要变化是:

我)应该是@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/

+0

你需要使这些字符串的正则表达式对象: ) – 2010-09-16 07:44:02

+0

我想知道OP是否确实需要一个正则表达式?如果是这样,那么'我的@regexes_to_filter_a =(qr/tmp /,qr/temp /,qr/del /);'是必需的。 – draegtun 2010-09-16 07:58:35

+0

+1谢谢draegtun!愚蠢的我 - 我使用'()'而不是'[]'作为数组引用。 – 2010-09-16 08:45:23

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/*"); 
+0

我认为他正试图避免显式循环和智能匹配数组正则表达式。 – cjm 2010-09-16 07:40:52

+0

我只想获取$ root_dir下的所有子目录的完整路径,除了那些匹配其中一个正则表达式的目录。 – 2010-09-16 08:39:42