2013-03-30 70 views
1

我一直在寻找一个解决方案,我的问题和哈希似乎是阅读几篇文章后的答案,但我不确定如何实现这个我的要求,任何人都可以建议如何甚至更好的选择?引用变量中的变量 - 哈希?

在我的代码中,变量$host正在根据数据库中的值进行设置。我遍历这些值,每次更改$host的值。

我想丢弃一些类型的主机名,并确定哪些主机丢弃我读取在一个用户可配置的文件,该文件包含该排除的Perl正则表达式。即配置文件中有一行

EXCLUDE=\d+DAT\d+,\d+INF\d+ 

我当时想建立Perl的正则表达式匹配(逻辑OR),即

if ($host =~ m/\d+DAT\d+/ || $host =~ m/\d+INF\d+/) { 
    # do something 
} 

目前我的代码是硬接线如在上面的例子,但是如何在读取配置文件后动态构造Perl正则表达式?

我已经读取配置文件到一个数组,并将从那里开始。上面的代码需要落得这样的:

if ($exclude clause) { 
    # do something 
} 

这是我如何着手实现从阵列读取:

for ($i = 1; $i < @conf; $i++) { 
    $exclude_clause .= "$host =~/" . @conf[$i] . "/ || "; 
} 
$exclude_clause =~ s/ \|\| $//; 

问题是$exclude_clause中引用$host。除了$host之外,我的正则表达式字符串是内置的。

+0

到底是什么问题?这是你试图运行的实际代码吗? – lmsteffan

回答

0

我会建议一种不需要你建立一个大的正则表达式字符串然后进行评估的方法。相反,如果使用List::MoreUtils模块的any函数(它接受一个代码块)对列表中的每个成员进行求值,并且一旦该块对列表中的至少一个条目返回true,则返回true。例如:

use List::MoreUtils qw{ any }; 

if (any { $host =~ $_ } @conf) { 
    # do something 
} 

在传递给any码块,临时变量$_包含列表中的当前条目。这样可以避免首先构建正则表达式。

+0

这听起来是一个整洁的解决方案,只是为了确认 - 如果我的@conf数组值是\ d + DAT \ d +(位置1)和\ d + INF \ d +(pos2)等等,那么每个测试都会进行正则表达式匹配反对$主机&应该任何匹配然后#做一些事情。 – user2008555

+0

我刚刚尝试运行上述建议,我收到错误“无法调用方法”任何“没有包或对象引用........线193” - 行193如下所示: - 如果(任何{$主机=〜M/$ _ /} @conf){ #do东西 } 我已经安装列表:: MoreUtils,这是在我的代码 “使用名单:: MoreUtils” 有什么建议吗? Mark – user2008555

+0

我应该写'use List :: MoreUtils qw {any};'。上面更新了我的答案。 –

0

我认为你应该在配置文件中存储完整的正则表达式,但如果需要的话,它可以是一组逗号分隔的替代方案。

你会使用qr//结构来构建正则表达式:

my $exc1 = "\d+DAT\d+"; # Read from configuration file 
my $ecc2 = "\d+INF\d+"; 

my $rex1 = qr/$exc1/; 
my $rex2 = qr/$exc2/; 

...populate $host... 

if ($host =~ $rex1 || $host =~ $rex2) 
{ 
    ...exclude $host... 
} 
else 
{ 
    ...include $host... 
} 

或者,您可以建立一个单一的正则表达式:

my $exc1 = "\d+DAT\d+"; # Read from configuration file 
my $ecc2 = "\d+INF\d+"; 

my $rex = qr/$exc1|$exc2/; 

...populate $host... 

if ($host =~ $rex) 
{ 
    ...exclude $host... 
} 
else 
{ 
    ...include $host... 
} 

单正则表达式可以从许多替代排除正则表达式来建片段,如你所愿。当然,如果该文件中的值是:

EXCLUDE=\d+DAT\d+|\d+INF\d+ 

那么你的代码,来简化一次,假设正则表达式的字符串被读入$exc

my $exc = "\d+DAT\d+|\d+INF\d+"; # Read from file 
my $rex = qr/$exc/; 

...populate $host... 

if ($host =~ $rex) 
{ 
    ...exclude $host... 
} 
else 
{ 
    ...include $host... 
}