How do I build Perl regular expressions dynamically?

后端 未结 6 1592
-上瘾入骨i
-上瘾入骨i 2021-02-08 15:24

I have a Perl script that traverses a directory hierarchy using File::Next::files. It will only return to the script files that end in \".avi\", \".flv\", \".mp3\", \".mp4\", a

6条回答
  •  萌比男神i
    2021-02-08 16:24

    Assuming that you've parsed the configuration file to get a list of extensions and ignored directories, you can build the regular expression as a string and then use the qr operator to compile it into a regular expression:

    my @extensions = qw(avi flv mp3 mp4 wmv);  # parsed from file
    my $pattern    = '\.(' . join('|', @wanted) . ')$';
    my $regex      = qr/$pattern/;
    
    if ($file =~ $regex) {
        # do something
    }
    

    The compilation isn't strictly necessary; you can use the string pattern directly:

    if ($file =~ /$pattern/) {
        # do something
    }
    

    Directories are a little harder because you have two different situations: full names and suffixes. Your configuration file will have to use different keys to make it clear which is which. e.g. "dir_name" and "dir_suffix." For full names I'd just build a hash:

    %ignore = ('.svn' => 1);
    

    Suffixed directories can be done the same way as file extensions:

    my $dir_pattern = '(?:' . join('|', map {quotemeta} @dir_suffix), ')$';
    my $dir_regex   = qr/$dir_pattern/;
    

    You could even build the patterns into anonymous subroutines to avoid referencing global variables:

    my $file_filter    = sub { $_ =~ $regex };
    my $descend_filter = sub {
        ! $ignore{$File::Next::dir} &&
        ! $File::Next::dir =~ $dir_regex;
    };
    
    my $iter = File::Next::files({
        file_filter    => $file_filter,
        descend_filter => $descend_filter,
    }, $directory);
    

提交回复
热议问题