1

我一直在寻找解决我的问题的方法,在阅读了几篇文章后,哈希似乎是答案,但我不确定如何根据我的要求实现这一点,有人可以建议如何甚至更好的选择吗?

在我的代码中,变量$host是从数据库中的值设置的。我循环遍历这些值,改变$host每次的值。

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

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

然后我想建立 Perl 正则表达式匹配(逻辑或),即

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/ \|\| $//;

问题是$host$exclude_clause. 我的正则表达式字符串除了$host.

4

2 回答 2

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...
}
于 2013-03-31T00:46:29.597 回答
0

我会建议一种不同的方法,它不需要您构建一个大的正则表达式字符串然后对其进行评估。相反,如何使用List::MoreUtils模块的any函数,它接受一个代码块,为列表的每个成员评估它,并在该块为列表中的至少一个条目返回 true 时返回 true。例如:

use List::MoreUtils qw{ any };

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

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

于 2013-03-30T17:12:54.153 回答