如何匹配perl中的字符串与变量而不是正则表达式

时间:2015-01-04 08:51:47

标签: arrays regex string perl string-matching

我想要使用perl检测一组文件名。

我有很多这些,但这个例子只是为了说明:

@toremove = (100, 102, 104, 131, 156);

现在我想打开目录并浏览文件,如果它们碰巧有上面数组中的任何文件名,我想采取一些行动。

opendir (DIR, "D:/MYPATH/");
while (my $file = readdir(DIR)) {
    if($file =~ <how do i reference an array item here?>.txt)
    { // do something }

有没有办法说该文件是否恰好匹配数组中的任何项目?所以这更像是一个&#34;变量字符串匹配&#34; ...

4 个答案:

答案 0 :(得分:2)

我首先将数组转换为哈希值,然后简单地测试哈希值中是否存在键。

my @toremove = (100, 102, 104, 131, 156);
my %lookup_hash;
$lookup_hash{"$_.txt"} = 1 for @toremove;

opendir (my $DIR, "D:/MYPATH/");
while (my $file = readdir($DIR)) {
    if( $lookup_hash{$file} )
    { // do something }

答案 1 :(得分:2)

每当你对自己说如何快速找到列表中的内容时,你应该对自己说哈希!

让我们选择@toremove列表,并将其转换为哈希值。我们可以使用map命令执行此操作。 map命令起初有点吓人,我不相信它的联机帮助是正确的。它并不是那么复杂:

 @some_hash_or_array = map { .... } @original_array;

map接受@original_array并循环遍历该数组的每个条目。 {...}是您希望在每个条目上运行的小程序。

您可以将map视为某事,如下所示:

my @original_array = qw( ... );
my @some_hash_or_array;
for my $entry ( @original_array ) {
    push @some_hash_or_array, { ... };
}

使map有用的原因是数组的每个条目都设置为$_,因此操纵$_可以转换数组。

我在做的是:

my %files = map { $_.".txt" => 1 } @to_remove;

当这个map命令处理@to_remove时,它会创建另一个如下所示的数组:

("100.txt" => 1, "102.txt" => 1, "104.txt" => 1, "131.txt" => 1, "156.txt" => 1)

我用这个数组初始化我的%files哈希。奇数条目是哈希的,密钥后面的偶数条目是数据。

#! /usr/bin/env perl
#
use strict;             # Lets you know when you misspell variable names
use warnings;           # Warns of issues (using undefined variables)
use feature qw(say);

my @to_remove = qw(100 102 104 131 156);

my %files = map { $_.".txt" => 1 } @to_remove;
while ( my $file = <DATA> ) {
    chomp $file;
    if ( exists $files{$file} ) {
        say qq(File "$file" is in the list);
    }
    else {
        say qq(File "$file" isn't in the list);
    }
}

__DATA__
100.txt
203.txt
130.txt
104.txt
150.txt
156.txt
160.txt

这会产生:

File "100.txt" is in the list
File "203.txt" isn't in the list
File "130.txt" isn't in the list
File "104.txt" is in the list
File "150.txt" isn't in the list
File "156.txt" is in the list
File "160.txt" isn't in the list

您需要这样做:

#! /usr/bin/env perl
#
use strict;             # Lets you know when you misspell variable names
use warnings;           # Warns of issues (using undefined variables
use autodie;            # Automatically kills the program if opens fail
use feature qw(say);

my @to_remove = qw(100 102 104 131 156);
opendir my $dir_fh, "dir_name";

my %files = map { $_.".txt" => 1 } @to_remove;
while ( my $file = < $dir_fh > ) {
    if ( exists $files{$file} ) {
        say qq(File "$file" is in the list);
    }
    else {
        say qq(File "$file" isn't in the list);
    }
}

答案 2 :(得分:1)

我转换数组的每个元素,然后使用智能匹配运算符:

#!/usr/bin/perl
use Modern::Perl;

my @toremove = (100, 102, 104, 131, 156);
my @txt = map{$_.'.txt'}@toremove;
while(<DATA>) {
    chomp;
    if ($_ ~~ @txt) {
        say "==> $_ : found";
    } else {
        say "$_ : NOT found";
    }
}

__DATA__
abc
def.txt
100
102.txt
131.abc
156.txt

<强>输出:

abc : NOT found
def.txt : NOT found
100 : NOT found
==> 102.txt : found
131.abc : NOT found
==> 156.txt : found

答案 3 :(得分:0)

以下是两种选择:

##  Shorthand hash definition
@toremove{100, 102, 104, 131, 156}= (1) x 5;

##  Using a glob instead of opendir
for (<D:/MYPATH/*>)
{
    ##  Use a regex for flexibility
    if (m:.*/(.+)$: and $toremove{$1})
    {
        print "Doing something to $_\n";
    }
}