perl - 将紧凑字符串反向转储到 Perl 中的变量中

标签 perl parsing dump

我有一个这样的结构:

my %Tr106IPInterfaceXsListSyntax = (
      tr69InstanceId22079 => {type => 'INTEGER', Ordinal => 0},
      tr106IPv4AddressXsBifoldList_001 => {
        type => [
          { Tr106IPv4AddressXsBifoldListSyntax => {
            tr69InstanceId22082 => {type => 'INTEGER', Ordinal => 0},
            iPAddress21929 => {type => 'STRING', Ordinal => 1},
            subnetMask21930 => {type => 'STRING', Ordinal => 2},
            addressingType22310 => {type => 'ENUMERATION', Ordinal => 3}
            }
          }
        ],
        Ordinal => 1
      },       
      tr106IPv6AddressXsBifoldList_001 => {
         type => [
          { Tr106IPv6AddressXsBifoldListSyntax => {
            tr69InstanceId22330 => {type => 'INTEGER', Ordinal => 0},
            iPAddress22326 => {type => 'STRING', Ordinal => 1},
            origin22327 => {type => 'ENUMERATION', Ordinal => 2}
            }
          }
        ],
        Ordinal => 2
      },
      iPv4Enable22321 => {type => 'BOOLEAN', Ordinal => 3},
      status21926 => {type => 'ENUMERATION', Ordinal => 4},
      name22274 => {type => 'STRING', Ordinal => 5},
      lastChange21927 => {type => 'INTEGER', Ordinal => 6},
      lowerLayers22080 => {type => [ 'STRING' ], Ordinal => 7},
      type22309 => {type => 'ENUMERATION', Ordinal => 8},
      iPv4AddressNumberOfEntries21928 => {type => 'INTEGER', Ordinal => 9},
      iPv6AddressNumberOfEntries22322 => {type => 'INTEGER', Ordinal => 10},
      iPv6Enable22323 => {type => 'BOOLEAN', Ordinal => 11}
    );

从外部源我得到一个像这样的字符串:

"[{1,[{1,'10.16.195.16','255.255.254.0',DHCP}],[],true,UP,'',0,[''],NORMAL,1,0,false},{2,[{1,'10.15.128.69','255.255.255.255',IKEV2}],[],false,UP,'4g_core_tunnel',1,[''],TUNNEL,1,0,false}]"

或者相同的字符串打印漂亮

"[
  { 1, 
    [ {1, '10.16.195.16', '255.255.254.0', DHCP} ],
    [ ],
    true,
    UP,
    '',
    0,
    [''],
    NORMAL,
    1,
    0,
    false
  },
  { 2,
    [ {1, '10.15.128.69', '255.255.255.255', IKEV2 } ],
    [],
    false,
    UP,
    '4g_core_tunnel',
    1,
    [''],
    TUNNEL,
    1,
    0,
    false
   }
]"

如何将这个紧凑的字符串转换为像这样的可用变量:

my $var = [
   {
      tr69InstanceId22079 => 1,
      tr106IPv4AddressXsBifoldList_001 => [
         { 
            tr69InstanceId22082 => 1,
            iPAddress21929 => '10.16.195.16',
            subnetMask21930 => '255.255.254.0',
            addressingType22310 => "DHCP"
         }
      ],       
      tr106IPv6AddressXsBifoldList_001 => [],
      iPv4Enable22321 => "true",
      status21926 => "UP",
      name22274 => '',
      lastChange21927 => 0,
      lowerLayers22080 => [ '' ],
      type22309 => "NORMAL",
      iPv4AddressNumberOfEntries21928 => 1,
      iPv6AddressNumberOfEntries22322 => 0,
      iPv6Enable22323 => "false"
   },
   {
      tr69InstanceId22079 => 2,
      tr106IPv4AddressXsBifoldList_001 => [
         { 
            tr69InstanceId22082 => 1,
            iPAddress21929 => '10.15.128.69',
            subnetMask21930 => '255.255.255.255',
            addressingType22310 => "IKEV2"
         }
      ],       
      tr106IPv6AddressXsBifoldList_001 => [],
      iPv4Enable22321 => "false",
      status21926 => "UP",
      name22274 => '4g_core_tunnel',
      lastChange21927 => 1,
      lowerLayers22080 => [ '' ],
      type22309 => "TUNNEL",
      iPv4AddressNumberOfEntries21928 => 1,
      iPv6AddressNumberOfEntries22322 => 0,
      iPv6Enable22323 => "false"
   }   
]

在我的脚本中,我有大约 30 种不同的结构,因此最好它应该是通用的(即动态且最有可能是递归的)解决方案。我想我必须编写一个正则表达式,然后逐一处理这些组。也许有一个模块可以做到这一点,而我不必重新发明轮子。

最佳答案

这是一个两阶段问题。首先,您必须将字符串转换为可行的 Perl 结构。

假设您可以控制收到的数据,则可以使用 eval。

use strict;
use warnings;
my $data_as_string = "[{1,[{1,'10.16.195.16','255.255.254.0',DHCP}],[],true,UP,'',0,[''],NORMAL,1,0,false},{2,[{1,'10.15.128.69','255.255.255.255',IKEV2}],[],false,UP,'4g_core_tunnel',1,[''],TUNNEL,1,0,false}]";

# Change {} into [] as we dont have the attributes ye
$data_as_string =~ s/\{/[/g;
$data_as_string =~ s/\}/]/g;

# Quote String constants.
$data_as_string =~ s/(?<=[,\[])(\w*[a-z]\w*)(?=[,\]])/'$1'/ig;

my $data = eval $data_as_string;

然后你必须迭代结果并生成你的对象。最简单的方法是为每种类型编写一个函数。

my @result;
foreach my $ele (@$data) {
    push @result, get_Tr106IPInterfaceXs( $ele);
}

sub get_Tr106IPInterfaceXs {
    my $array = shift;
    return 
    {
      tr69InstanceId22079 => $array->[0],
      tr106IPv4AddressXsBifoldList_001 => [
        map {get_tr106IPv4AddressXsBifold($_)} @{$array->[1]}
      ],       
      tr106IPv6AddressXsBifoldList_001 => $array->[2],
      iPv4Enable22321 => $array->[3],
      status21926 => $array->[4],
      name22274 => $array->[5],
      lastChange21927 => $array->[6],
      lowerLayers22080 => $array->[7],
      type22309 => $array->[8],
      iPv4AddressNumberOfEntries21928 => $array->[9],
      iPv6AddressNumberOfEntries22322 => $array->[10],
      iPv6Enable22323 => $array->[11]
    }
}

sub get_tr106IPv4AddressXsBifold {
    my $array = shift;
    return  { 
            tr69InstanceId22082 => $array->[0],
            iPAddress21929 => $array->[1],
            subnetMask21930 => $array->[2],
            addressingType22310 => $array->[3]
    }
}

添加

use Data::Dumper;
print Dumper \@result;

最后,按预期打印出所有内容。

关于perl - 将紧凑字符串反向转储到 Perl 中的变量中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77079363/

相关文章:

c - C语言中如何从字符串中提取多个数字

svn - 如何从某些修订/推送中删除 Mercurial 存储库

mysql - 以下哪种方法导入数据库更快?

mysql - (Ruby) 如何转储数据库?

Perl 子程序数组和标量变量参数

perl - 如何连接路径名和相对路径名?

perl - 发送 Edited bug 时的 bugzilla 邮件格式

perl - perl *.t 的参数化 证明现有的测试

java - 安卓服务器: Parse server gradle build

iphone - 如何在 iPhone 中解析 Json 值?