我有以下要求
MANAGEMENT=IDL||CIDL
NORTH=IDL,NORTHERN||VIDL,NORTH||IDL,NORTH
SOUTH=IDL,SOUTHERN||CIDL,SOUTH||IDL,SOUTH
此处的每个键都可以包含多个这样的值','表示AND操作和'||'是OR操作
我需要针对另一个字符串$ instance和每个值进行检查,因此我采用第一个密钥管理并获取其值并检查isntance ....
$instance
包含IDL
或CIDL
在下一次迭代中,将针对第二个键NORTH
检查相同的实例,如果为true,则该函数应返回NORTH,所以基本上我需要逐个检查每个值的实例,然后返回键我发现最后......下面是编写到现在的代码
#!/sbin/perl -w
use strict;
use Data::Dumper;
my @providerCloudSequence;
my %idlcodes;
open(my $iniFH, '<', '/tmp/user_defined_connection.ini')
or die "Unable to open file:$!\n";
while(<$iniFH>) {
chomp;
my @providerCloudClass = split('=',$_);
push @providerCloudSequence, $providerCloudClass[0];
if ($@) {
print "Script Failed to get the Sequence....Exiting the Script\n";
exit 1;
}
#my %idlcodes = map { split /=|\s+/; } <$iniFH>;
my ($k, @r) = split /=|\Q||/;
$idlcodes{$k} = [ map [ split /,/ ], @r ];
}
if($@){
print "Script Failed to create the hash....Exiting the Script\n";
exit 1;
}
close $iniFH;
print Dumper \%idlcodes;
my @interfaceSampleAliases = { "AFGHD_NORTH",
"NORTHERN_IIDID_IPV123",
"IDL_SOUTH",
"IDL_SOUTH_IUID",
"SOUTHERN_IND_IPV" };
foreach (@interfaceSampleAliases){
my $correctKey = getCorrectKey($_, %idlcodes, @providerCloudSequence)
print $correctKey;
}
}
# Providercloudsequence helps to maintain the precedence of the input file
# idlcodes is the hasp map where key is the key from file and value is an arracy of arrays ...see below the output of same
sub getCorrectKey($$$){
my $interfaceAlias = $_[0];
foreach ($_[2]) {
# This is where I need the help , I want to get the value from
# hash %idlcodes using the key from @providerCloudSequence
# The value of %idlcodes is kind of multiple Arrays where I want to
# grep $interfaceAlias against each with a AND in between elements
# and OR in between arrays , if true this is match
}
}
##数据转储输出:哈希看起来像
'NORTH_IPV' => [
[
'IDL',
'NORTHERN'
],
[
'VIDL',
'NORTH'
],
[
'IDL',
'NORTH'
]
],
'MANAGEMENT' => [
[
'IDL'
],
[
'CIDL'
]
],
'SOUTH_IPV' => [
[
'IDL',
'SOUTHERN'
],
[
'CIDL',
'SOUTH'
],
[
'IDL',
'SOUTH'
]
]
预期产出
InterfaceAlias correctKey
"AFGHD_NORTH" Doesnt Match anything so return NULL
"NORTHERN_IIDID_IPV123" Doesnt Match anything so return NULL
"IDL_SOUTH", SOUTH_IPV
"IDL_SOUTH_IUID", SOUTH_IPV
"SOUTHERN_IND_IPV" Doesnt Match anything so return NULL
"IDL_NORTH_IPV" NORTH_IPV
"IDL_ABDGJF" MANAGEMENT
此示例中的检查应如何工作
检查InterfaceAlias是否包含(IDL OR CIDL),然后检查相同的interfaceAlias是否包含[(IDL AND NORTH)OR(VIDL AND NORTH)或(IDL AND NORTHERN),然后检查相同的interfaceAlias是否包含[(IDL AND SOUTH))或(CIDL和SOUTH)或(IDL和SOUTHERN)]
因此我们必须检查hash%idlcodes中的所有值并返回匹配为TRUE的最后一个键
序列由数组@providerCloudSequence
单词的邻接并不重要例如SOUTH_XXX_CIDL甚至“SOUTH IDL IPV WITH SPACES”应该匹配SOUTH_IPV ....这些只是示例它基本上是一个包含匹配....虽然文件的结构是固定的。 ..(数据可能有所不同)
答案 0 :(得分:1)
我想我会从ini文件构建一个正则表达式表,然后逐个比较字符串。
我建议的代码如下。 get_correct_key
现在将所有下划线转换为连字符并跳出所有垃圾,例如,SOUTH-GWS-F-IDL100555236-Primary-1Gb
转换为SOUTH-GWS-F-IDL-Primary-Gb
。这使我能够大大简化正则表达式。
关于代码的一些注意事项
优于use warnings
,而不是将-w
添加到shebang行
标识符中的大写字母通常保留给像包这样的全局字符,任何熟悉Perl的人都会感谢你坚持使用简单变量和子程序的小写和下划线
$@
仅在一段Perl代码无法编译或调用die
时设置。它仅由eval
捕获,如果您不使用它,则$@
上的测试将始终失败
你应该从不在Perl子例程定义上使用原型。它们与其他语言的原型不同,并且不按照您的想法进行操作
我希望这会有所帮助
use strict;
use warnings;
open my $ini, '<', 'user_defined_connection.ini' or die $!;
my @provider_patterns;
while (<$ini>) {
next unless /\S/;
chomp;
my ($key, $data) = split /=/, $_, 2;
my $regex = join " |\n", map {
join ' ', map { "(?=.* \\b $_ \\b )" } split /,/;
} split /\|\|/, $data;
push @provider_patterns, [ qr/$regex/xi, $key ];
}
my @aliases = (
'AFGHD_NORTH',
'NORTHERN_IIDID_IPV123',
'IDL_SOUTH',
'IDL_SOUTH_IUID',
'SOUTHERN_IND_IPV',
'IDL_NORTH_IPV',
'IDL_ABDGJF',
'IDL SOUTH',
'MANAGEMENT_IPV_IDL100595208',
'SOUTH-GWS-F-IDL100555236-Primary-1Gb',
);
for my $alias (@aliases) {
my $found = get_correct_key($alias, \@provider_patterns);
printf qq{ %-38s %-s\n}, qq{"$alias"}, defined $found ? $found : "Doesn't match anything so return undef";
}
sub get_correct_key {
my ($alias, $patterns) = @_;
$alias =~ tr/_/-/;
$alias = join '-', $alias =~ /[a-z]+/gi;
my $found;
for my $pair (@$patterns) {
my ($re, $key) = @$pair;
$found = $key if $alias =~ $re;
}
$found;
}
<强>输出强>
"AFGHD_NORTH" Doesn't match anything so return undef
"NORTHERN_IIDID_IPV123" Doesn't match anything so return undef
"IDL_SOUTH" SOUTH_IPV
"IDL_SOUTH_IUID" SOUTH_IPV
"SOUTHERN_IND_IPV" Doesn't match anything so return undef
"IDL_NORTH_IPV" NORTH_IPV
"IDL_ABDGJF" MANAGEMENT
"IDL SOUTH" SOUTH_IPV
"MANAGEMENT_IPV_IDL100595208" MANAGEMENT
"SOUTH-GWS-F-IDL100555236-Primary-1Gb" SOUTH_IPV