2010-09-16 40 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