Perl正则表达式多行匹配为哈希

use*_*417 4 regex perl hash

我已经成功解析了一个cisco配置文件,并使用以下多行正则表达式抓取了每个标记之间的配置部分(cisco使用了!符号):

/(search string)/i .. /^!/ 
Run Code Online (Sandbox Code Playgroud)

我的代码如下:

#!/usr/bin/perl -w
use strict;
use Data::Dumper;

my (@results, @data) ;

#Test data to simulate a while loop on a file-handle running through a config file.
@data =  (
    "vlan 81" ,
    " name Vlan 81 test1" ,
    "!" ,
    "vlan 82" ,
    " name Vlan 82 test2" ,
    "!" ,
    "vlan 83" ,
    " name Vlan 83 test3" ,
    "!"
);

foreach ( @data ) {
    if ( /vlan/i .. /^!/ ) {
         push  (@results , $_) ;                
    }
}

print Dumper ( @results ) . "\n" ;

exit;
Run Code Online (Sandbox Code Playgroud)

它确实工作得很好,但是我想将结果推送到一个哈希中,每个代码段都是一个匿名数组,因此结果看起来像:

%Vlan -> [Vlan 81, name Vlan 81 test1] , [Vlan 82, name Vlan 82 test2] , [Vlan 83, name Vlan 83 test3]
Run Code Online (Sandbox Code Playgroud)

但是我不知道该怎么做,我的代码在搜索字符串和标记之间的每一行都匹配,最后我将结果逐行重建到另一个数组中。

任何帮助深表感谢。

干杯,

安迪

Bor*_*din 5

我不确定您对哈希的含义,因为您描述的内容只是一个匿名数组列表。没有键,因此只能产生一个数组。如果您可以解释数据的哪一部分是关键,那么我们可以进行哈希处理。

语用use warnings-wshebang修饰符更可取,因为它更灵活并且可以被否定。

范围运算符..可能很可爱,但是您绝不能在任何可能的地方使用它。

将输入分隔符设置为,"!\n"将允许您一次读入所有相关行,然后可以将其压入数组。

代码看起来像这样

use strict;
use warnings;

use Data::Dumper;

my @Vlan;

$/ = "!\n";

while  (<DATA>) {
  chomp;
  push @Vlan, [split /[\r\n]+/];
}

print Data::Dumper->Dump([\@Vlan], ['*Vlan']);

__DATA__
vlan 81
name Vlan 81 test1
!
vlan 82
name Vlan 82 test2
!
vlan 83
name Vlan 83 test3
!
Run Code Online (Sandbox Code Playgroud)

输出

@Vlan = (
          [
            'vlan 81',
            'name Vlan 81 test1'
          ],
          [
            'vlan 82',
            'name Vlan 82 test2'
          ],
          [
            'vlan 83',
            'name Vlan 83 test3'
          ]
        );
Run Code Online (Sandbox Code Playgroud)

编辑

如果哈希键始终是记录集的第一行,则此程序将根据您的要求生成一个哈希

use strict;
use warnings;

use Data::Dumper;

my %Vlan;

$/ = "!\n";

while  (<DATA>) {
  chomp;
  my ($k, $v) = split /[\r\n]+/;
  $Vlan{$k} = $v;
}

print Data::Dumper->Dump([\%Vlan], ['*Vlan']);

__DATA__
vlan 81
name Vlan 81 test1
!
vlan 82
name Vlan 82 test2
!
vlan 83
name Vlan 83 test3
!
Run Code Online (Sandbox Code Playgroud)

输出

%Vlan = (
          'vlan 81' => 'name Vlan 81 test1',
          'vlan 83' => 'name Vlan 83 test3',
          'vlan 82' => 'name Vlan 82 test2'
        );
Run Code Online (Sandbox Code Playgroud)