Perl如何构建动态的多级哈希查找 [英] Perl How to build a Dynamic multi level hash lookup

查看:68
本文介绍了Perl如何构建动态的多级哈希查找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代码块,该代码块使用了很多次,但有一些细微的变化,我试图将其变成子例程.此代码块完成配置模板(路由器接口,VRRF,其他网络内容)

I have a code block that i use many times with slight variations that i am trying to make into a subroutine. This code block Completes configuration templates ( router interface, vrf, other network stuff)

通过在通过导入excel文件:P构建的哈希数据结构(称为%config_hash)中查找数据来做到这一点.查找的数据位于不同模板的散列的不同区域.

It does so by looking up data in a hash data structure ( called %config_hash) that is built from ingesting a excel file :P. The data that is looked up is in different areas of the hash for different templates.

当前工作代码的一个示例是:

an example of the current working code is this:

my @temp_source_template = @{ clone ($source_template{$switch_int_template}) };

            my %regex_replacements=();                                                  ## hash for holding regex search and replace values, keys are !name! (look in template files) values taken from DCAP
            my @regex_key =();                                                          ## temp array used for whe more then one !name! on a line
            my $find_string='';
            foreach my $line (@temp_source_template){
                my (@regex_key) = ( $line =~ /(\!.*?\!)/g );                        ## match needs to be non greedy thus .*? not .*
                foreach my $hash_refs (@regex_key){
                    my $lookup = $hash_refs =~ s/!//gri;                            ## remove ! from !name! so lookup can be done in DCAP file hash
                    my $excel_lookup = $lookup =~ s/_/ /gri;
                    $regex_replacements{$hash_refs} = $config_hash{'Vlan'}{$inner}{$excel_lookup};          ## lookup DCAP file hash a write value to regex hash
                    if (undef eq $regex_replacements{$hash_refs}){
                        $regex_replacements{$hash_refs} = $config_hash{'Switch'}{$outer}{$excel_lookup};
                    }
                    if (undef eq $regex_replacements{$hash_refs}){
                        $regex_replacements{$hash_refs} = $config_hash{'VRF'}{$middle}{$excel_lookup};
                    }
                    $find_string= $find_string . $hash_refs . '|' ;

                }

            }

因此,这将创建一个哈希(regex_replacements),其中包含要查找的值(regex_replacements中的哈希键)和替换为的值(regex_replacements中的值).它还构建了一个用于正则表达式的字符串($ find_string).不同的模板将具有不同的哈希查找路径"(例如$ config_hash {'Switch'} {$ outer} {$ excel_lookup})或具有不同的顺序(实际上是最具体的匹配项)

So this creates a hash (regex_replacements) that contains values to lookup (hash keys in regex_replacements) and values to replace those with (values in regex_replacements). it also builds a string to be used in a regex expression ( $find_string). Different templates will have different hash lookup "paths" ( eg $config_hash{'Switch'}{$outer}{$excel_lookup} ) or in different orders (effectively a most specific match)

为完整起见,以下是执行正则表达式替换的代码块:

for completeness here is the code block that does the regex replacements:

foreach my $line (@temp_source_template){
    my (@line_array) = split /(![A-Za-z_]*!)/, $line;
    foreach my $chunk (@line_array){
        my $temp_chunk = $chunk;
        $chunk =~ s/($find_string)/$regex_replacements{$1}/gi;
        if (!($chunk)){
            $chunk = $temp_chunk;
        }
    }
    $line = join ("", @line_array);

    if ($line =~ /\!.*\!/){
        print {$log} " ERROR line has unmatched variables deleting line \"$line\"\n";
        $line ="";
    }
}

所以我做了一些搜索,发现了: Perl:如何将数组转换为嵌套的哈希键几乎完全是我想要的,但是我无法使它正常工作,因为我的变量引用是哈希,并且其哈希变量引用只是"REF",因此在尝试使用哈希作为引用时出现错误.

So I did some searching and i found this: Perl: How to turn array into nested hash keys Which is almost exactly what i want but i can't get it to work because my Variable reference is a Hash and its hash variable reference is just "REF" so i get errors for trying to use a hash as a reference.

所以我不会发布我尝试过的内容,因为我不太了解该链接的魔力.

So I wont post what i have tried as i don't really understand the magic of that link.

但是我正在做的是将以下内容传递给sub

But what i am doing is passing to the sub the following

            my @temp_source_template = @{ clone ($source_template{$test}) };
        my @search_array = ( ['VRF' ,$middle] , ['Switch' ,$outer]);
        my $find_string, $completed_template = dynamic_regex_replace_fine_string_gen(\%source_config,\@temp_source_template, \@search_array);

,我想返回$ find_string和regex_replacements哈希引用.应该注意的是,在子目录中,我需要在@search数组的元素末尾附加$ excel_lookup的值.

and i want returned the $find_string and the regex_replacements hash ref. It should be noted that in the sub i need to append onto the end of the elements of @search array the value of $excel_lookup.

我不知道该怎么做的一点是建立可变级别的哈希查找.

The bit that i dont understand how to do is build the variable level hash lookup.

推荐答案

您可以尝试使用 Data :: Diver 它提供了对深度嵌套结构的元素的简单访问.

You could try use Data::Diver it provides a simple access to elements of deeply nested structures.

例如:

use feature qw(say);
use strict;
use warnings;
use Data::Diver qw(Dive);

my $hash = { a => { b => 1, c => { d => 2 }}};
my $keys = [[ 'a', 'b'], ['a','c','d']];
lookup_keys( $hash, $keys );

sub lookup_keys {
    my ( $hash, $keys ) = @_;

    for my $key ( @$keys ) {
        my $value = Dive( $hash, @$key );
        say $value;
    }
}

输出:

1
2

另请参见:

这篇关于Perl如何构建动态的多级哈希查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆