我需要从多行字符串中提取多个项目。
{
'autoname' => 1,
'class' => 'packetfilter',
'data' => {
'action' => 'accept',
'auto' => 0,
'auto_type' => '',
'comment' => 'Allow access to Sandbox Server',
'destinations' => [
'REF_NetworkAny'
],
'direction' => '',
'group' => 'SANDBOX',
'interface' => '',
'log' => 1,
'name' => 'TCP_5090 from SND (Network) to Any',
'services' => [
'REF_SerTcpTcp5090',
'REF_SerTcpTcp8200',
'REF_SerTcpTcp8883',
'REF_SerTcpTcpudp5090'
],
'source_mac_addresses' => '',
'sources' => [
'REF_MHTGIvpkvI'
],
'status' => 1,
'time' => ''
},
'hidden' => 0,
'lock' => '',
'nodel' => '',
'ref' => 'REF_PacPacTcp50FromSnd',
'type' => 'packetfilter'
}
我需要找到标签'服务',目的地和来源,并且只为每个标签提取REF标签。
示例:
services
REF_SerTcpTcp5090
REF_SerTcpTcp8200
REF_SerTcpTcp8883
REF_SerTcpTcpudp5090
destinations
REF_NetworkAny
sources
REF_MHTGIvpkvI
任何指导都将不胜感激。
答案 0 :(得分:2)
这肯定看起来像Perl。您可以使用eval
将其转换为Perl数据结构,但这会产生许多安全问题。
相反,使用the Safe module来评估它,但只允许某些运算符。这将阻止它执行某些不安全的操作,比如打开文件或添加函数。这是一个演示。
use v5.10;
use strict;
use warnings;
use Safe;
my $safe = Safe->new;
my $data = $safe->reval(join "", <DATA>) or die "reval failed: $@";
say join "\n", keys %$data;
__END__
{
'autoname' => 1,
'class' => 'packetfilter',
'data' => {
'action' => 'accept',
'auto' => 0,
'auto_type' => '',
'comment' => 'Allow access to Sandbox Server',
'destinations' => [
'REF_NetworkAny'
],
'direction' => '',
'group' => 'SANDBOX',
'interface' => '',
'log' => 1,
'name' => 'TCP_5090 from SND (Network) to Any',
'services' => [
'REF_SerTcpTcp5090',
'REF_SerTcpTcp8200',
'REF_SerTcpTcp8883',
'REF_SerTcpTcpudp5090'
],
'source_mac_addresses' => '',
'sources' => [
'REF_MHTGIvpkvI'
],
'status' => 1,
'time' => ''
},
'hidden' => 0,
'lock' => '',
'nodel' => '',
'ref' => 'REF_PacPacTcp50FromSnd',
'type' => 'packetfilter'
}
安全不是100%安全,所以你不应该养成这个习惯。如果可能的话,使用可解析的格式(如JSON)进行数据序列化。
答案 1 :(得分:1)
如果您的输入数据集是有效的Perl代码,最简单的方法应该是使用eval
评估代码,如其他答案所示。如前所述,如果您不信任输入数据的来源,则存在一些安全问题。因此,请仔细使用它并考虑使用模块来进一步缩小攻击面。
另一种解决方案可能是使用正则表达式。假设您在标量中包含完整的输入数据,则可以解析所需的项目
#!/usr/bin/env perl
use strict;
use warnings;
my $data = join "", <DATA>;
my @services = get_values(\$data, 'services');
my @destinations = get_values(\$data, 'destinations');
my @sources = get_values(\$data, 'sources');
print "Services: ", join(", ", @services),"\n";
print "Destinations: ", join(", ", @destinations),"\n";
print "Sources: ", join(", ", @sources),"\n";
sub get_values
{
my ($inputdata, $key) = @_;
# add quote signs around the key
$key = "'$key'";
if ($$inputdata =~ /$key => \[([^\]]+)\]/m)
{
# $1 contains the values
my $values = $1;
# remove empty lines, plus leading and tailing whitespaces
$values =~ s/^\s*$|^\s+|\s+$//mg;
# strip line breaks and single quotes
$values =~ s/[\n']//g;
# split into seperate fields
my @result = split(/,/, $values);
return @result;
} else {
return ();
}
}
__END__
{
'autoname' => 1,
'class' => 'packetfilter',
'data' => {
'action' => 'accept',
'auto' => 0,
'auto_type' => '',
'comment' => 'Allow access to Sandbox Server',
'destinations' => [
'REF_NetworkAny'
],
'direction' => '',
'group' => 'SANDBOX',
'interface' => '',
'log' => 1,
'name' => 'TCP_5090 from SND (Network) to Any',
'services' => [
'REF_SerTcpTcp5090',
'REF_SerTcpTcp8200',
'REF_SerTcpTcp8883',
'REF_SerTcpTcpudp5090'
],
'source_mac_addresses' => '',
'sources' => [
'REF_MHTGIvpkvI'
],
'status' => 1,
'time' => ''
},
'hidden' => 0,
'lock' => '',
'nodel' => '',
'ref' => 'REF_PacPacTcp50FromSnd',
'type' => 'packetfilter'
}
正则表达式方法的优点是不受信任的数据源没有(或至少减少)安全问题。
谢
编辑:添加了示例代码。
答案 2 :(得分:-1)
作为已经注意到的评论者之一 - 数据是有效的perl - 可能由Data :: Dumper或类似的东西创建。要获取数据,只需评估它:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<a href="#section1">Section 1</a>
<!--For demo-->
<div class="spacer"></div>
<fieldset class="collapsed">
<legend id="section1"><a href="#section1">Heading</a></legend>
<div class="content">
..content XXXXX xxxxxxxxxxxnnnnnnnnnnnnn hbyigyugvyibrgh fwgewg wefgeh bbbbb uhuhouihoijpiok erhtru efwgwrhnj
</div>
</fieldset>
请注意来自Data::Dumper documnetation;
的此警告给定一个标量或引用变量列表,用perl语法写出它们的内容。引用也可以是对象。每个变量的内容在单个Perl语句中输出。正确处理自引用结构。
可以回避返回值以获取原始参考结构的相同副本。 (请考虑来自不受信任来源的eval和代码的安全隐患!)