我有一个这样的结构:
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/