寻找一种优雅的方式来搜索文件名字符串中的许多文件扩展名

时间:2014-01-27 15:00:12

标签: regex perl search file-extension

我想知道文件是否具有特定的文件扩展名,在扩展名列表中选择。

我有这个初步想法:

my $file = "filename.zip";
my @allowedExts = ( '.zip', '.tar.gz', '.tar.bz2' );

my $found = 0;
foreach $ext (@allowedExts) {
  if (index($file, $ext) != -1) {
    $found = 1;
    last;
  }
}

print "found" if ($found);

有更简单的方法吗?

4 个答案:

答案 0 :(得分:4)

如果你真的有很多扩展(不只是三个),首先找到扩展,然后检查一个哈希来避免循环:

my $file = "filename.zip";
my @allowedExts = ( '.zip', '.tar.gz', '.tar.bz2' );

my %allowedExts;
@allowedExts{@allowedExts} = ();
my (undef, $ext) = split /(?=\.)/, $file, 2;

my $found = $ext && exists $allowedExts{$ext};

以上将从第一个.开始处理文件名中的所有内容;如果您在之前的文件名中有.,那么您可以将所有扩展程序组合成一个正则表达式:

my $file = "filename.zip";
my @allowedExts = ( '.zip', '.tar.gz', '.tar.bz2' );

my $found = $filename =~ ( join( '|', map quotemeta, @allowedExts ) . '\z' );

答案 1 :(得分:1)

index在这里不是一个好主意,如果扩展名本身位于文件名中间的某处,您可能会遇到非常意外的行为。

另外:总是 use strictuse warnings

字符串末尾的正则表达式匹配将是更好的解决方案,请参阅下面的代码。 $是一个元字符,用于匹配行尾(或在结尾处的换行符之前)

#!/usr/bin/perl                                                                                                                                                                                                                                              
use strict;
use warnings;

my $file = "filename.zip";
my @allowedExts = ( '.zip', '.tar.gz', '.tar.bz2' );

my $found = 0;
foreach my $ext (@allowedExts) {
    if ($file =~ /\Q$ext\E$/) {
        $found = 1;
        last;
    }
}

print "found" if ($found);

你可能会有很多其他想法来解决这个问题。与perl一样:TIMTOWTDI。

编辑: 正如@ikegami所建议的那样,应该对正则表达式进行转义,这样点就不会被视为元字符,而是字面匹配,\Q\E在正则表达式中转义元字符。

答案 2 :(得分:1)

use List::Util qw(first);

my $file = "filename.zip";
my @allowedExts = map qr/\Q$_$/, ( '.zip', '.tar.gz', '.tar.bz2' );

my $found = first { $file =~ /$_/ } @allowedExts;

答案 3 :(得分:0)

另一种方法是使用正则表达式。

构建正则表达式:

my @allowedExts = qw( .zip .tar.gz .tar.bz2 );
my $pat = join '|', map quotemeta, @allowedExts;
my $re  = qr/$pat\z/;

使用它:

my $file = "filename.zip";
print "Found\n" if $file =~ $re;