我正在使用Perl捕获某些指定文件夹中的文件名,这些文件夹中包含某些单词。这些文件名中的关键字是“offer”或“已清除”和“regup”或“regdn”。换句话说,“offer”或“clear”之一和“regup”或“regdn”之一必须在文件名中出现为正匹配。这两个单词可以是任何顺序,并且在它们前面和后面会出现字符/单词。匹配文件名的示例是:
2day_Agg_AS_Offers_REGDN-09-JUN-11.csv
我有一个正则表达式,成功地将每个匹配的文件名作为完整路径捕获,这是我想要的,但它似乎不优雅和低效。尝试稍好的代码都失败了。
工作方法:
# Get the folder names
my @folders = grep /^\d{2}-/, readdir DIR;
foreach my $folder ( @folders ) {
# glob the contents of the folder (to get the file names)
my @contents = <$folder/*>;
# For each filename in the list, if it matches, print it
foreach my $item ( @contents ) {
if ($item =~ /^$folder(?=.*(offers|cleared))(?=.*(regup|regdn)).*csv$/i){
print "$item\n";
}
}
}
尝试更短/更清洁的东西:
foreach my $folder ( @folders ) {
# glob the contents of the folder (to get the file names)
my @contents = <$folder/*>;
# Seems to determine that there are four matches in each folder
# but then prints the first matching filename four times
my $single = join("\n", @contents);
for ($single =~ /^$folder(?=.*(offers|cleared))(?=.*(regup|regdn)).*csv$/im) {
print "$&\n";#"Matched: |$`<$&>$'|\n\n";
}
}
我尝试了使用其他选项(/ img,/ ig等)的正则表达式的其他格式,并将正则表达式的输出发送到数组,但没有任何工作正常。我对Perl并不擅长,所以我很肯定我错过了一些让整个程序更有效率的大好机会。谢谢!
答案 0 :(得分:1)
仅收集包含offers
或cleared
AND regup
或regdn
my @contents = grep { /offers|cleared/i && /regup|regdn/i } <$folder/*>;
答案 1 :(得分:0)
为什么使用join而不是循环会更短或更干净?我会说它让它变得更复杂。你似乎在做什么只是根据条件松散地匹配
offers
或cleared
regup
或regdn
.csv
结尾。那么为什么不这样做呢:
if ( $file =~ /offers|cleared/i and
$file =~ /regup|regdn/i and
$file =~ /csv$/i)
您可能会对以下内容感兴趣:
use strict;
use warnings;
use File::Find;
my $dir = "/some/dir";
my @files;
find(sub { /offers|cleared/i &&
/regup|regdn/i &&
/csv$/i && push @files, $File::Find::name }, $dir);
哪个将完全排除readdir和其他循环的使用。 File::Find
是递归的。