2011-03-02 46 views
5

有沒有一種方法可以避免將它用於多重模式檢查?如何在Perl中檢查多重模式匹配

我可以撕毀數組中的所有模式,並檢查它是否與模式數組中的任何模式匹配?請考慮我有超過20個模式字符串的情況。

if( ($_=~ /.*\.so$/) 
    || ($_=~ /.*_mdb\.v$/) 
    || ($_=~ /.*daidir/) 
    || ($_=~ /\.__solver_cache__/) 
    || ($_=~ /csrc/) 
    || ($_=~ /csrc\.vmc/) 
    || ($_=~ /gensimv/) 
){ 
    ... 
} 
+0

@Eric好的..我很抱歉沒有做到這一點 – Arovit

回答

11

如果您可以使用Perl版本5.10,那麼有一個非常簡單的方法來做到這一點。 只需使用新的smart match (~~)運營商。

use warnings; 
use strict; 
use 5.10.1; 

my @matches = (
    qr/.*\.so$/, 
    qr/.*_mdb\.v$/, 
    qr/.*daidir/, 
    qr/\.__solver_cache__/, 
    qr/csrc/, 
    qr/csrc\.vmc/, 
    qr/gensimv/, 
); 

if($_ ~~ @matches){ 
    ... 
} 

如果你不能使用Perl 5.10,那麼我會用List::MoreUtils::any

use warnings; 
use strict; 
use List::MoreUtils qw'any'; 

my @matches = (
    # same as above 
); 

my $test = $_; # copy to a named variable 

if(any { $test =~ $_ } @matches){ 
    ... 
} 
+1

請注意,smartmatch現在被標記爲實驗性的,並且*將被刪除或更改,恕不另行通知。 (聽起來像這樣會在5.26中發生。)無論您的Perl版本如何,都應該使用後一種解決方案。 – ikegami

4

另一個預Perl 5.10的選擇是Regexp::Assemble,其將採取的模式列表和它們合併成一個單一的正則表達式,這將考驗所有原始條件一次。

+0

這可以更有效率,特別是如果模式測試是針對多個值。開始正則表達式匹配實際上相當昂貴。 – ikegami

1

你原來的代碼也可以寫成更漂亮是這樣的:

if( /.*\.so$/ 
    || /.*_mdb\.v$/ 
    || /.*daidir/ 
    || /\.__solver_cache__/ 
    || /csrc/ 
    || /csrc\.vmc/ 
    || /gensimv/ 
) { ... } 

這是因爲$_ =~ /foo/是一樣的只是/foo/。如果你有Perl 5.10或更高版本,我會按照Brad的建議去做,並使用智能匹配運算符。