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

ここではスマートマッチングは必要ありません。右側に単一の正規表現があり、左側に文字列がある~~も、同じように=〜になる可能性があります。あなたは何をしようとしているのですか?

試合には2つの方法があります。文字列をパターンとして使用する場合は、一致演算子を使用する必要があります。

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

現在のようにmatch演算子を使用したくない場合は、正規表現オブジェクトが必要です。

 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)そしてスマートマッチの使用に変更します。以下basename($subdir)は、(~~@regexes_to_filter_a配列にあることを確認します。したがって、配列をループして個々の正規表現チェックを行う必要はありません。

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

/ I3az /

于 2010-09-16T07:37:35.917 に答える