joe*_*rgd 7 regex macos perl parsing json
我想scutil用perl脚本从Mac OSX的命令中检索信息.
该工具生成的输出有点类似于JSON,但到目前为止,我找不到任何能够解析它的东西.
例:
scutil
> open
> show State:/Network/Service/0F70B221-EEF7-4ACC-96D8-ECBA3A15F132/IPv4
<dictionary> {
ARPResolvedHardwareAddress : 00:1b:c0:4a:82:f9
ARPResolvedIPAddress : 10.10.0.254
AdditionalRoutes : <array> {
0 : <dictionary> {
DestinationAddress : 10.10.0.146
SubnetMask : 255.255.255.255
}
1 : <dictionary> {
DestinationAddress : 169.254.0.0
SubnetMask : 255.255.0.0
}
}
Addresses : <array> {
0 : 10.10.0.146
}
ConfirmedInterfaceName : en0
InterfaceName : en0
NetworkSignature : IPv4.Router=10.10.0.254;IPv4.RouterHardwareAddress=00:1b:c0:4a:82:f9
Router : 10.10.0.254
SubnetMasks : <array> {
0 : 255.255.255.0
}
}
Run Code Online (Sandbox Code Playgroud)
我已经设法通过regexp检索特定元素,但由于我需要进行几个不同的查找,我正在寻找一种更智能,更通用的方法.
现在,在我通过编码另一个perl-parser来重新发明轮子之前,我希望有人能够识别这种格式并且可以给出一些建议如何解析这个 - 比方说 - 一个嵌套的perl哈希映射.
任何评论欢迎.
在Perl中,您可以使用Marpa :: R2,这是Marpa的Perl接口,后者是常规BNF解析器。
这是一个简单的示例:
use 5.010;
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Terse = 1;
$Data::Dumper::Deepcopy = 1;
use Marpa::R2;
my $g = Marpa::R2::Scanless::G->new( { source => \(<<'END_OF_SOURCE'),
:default ::= action => [ name, value]
lexeme default = action => [ name, value] latm => 1
scutil ::= 'scutil' '> open' '> show' path '<dictionary>' '{' pairs '}'
path ~ [\w/:\-]+
pairs ::= pair+
pair ::= name ':' value
name ~ [\w]+
value ::= ip | mac | interface | signature | array | dict
ip ~ octet '.' octet '.' octet '.' octet
octet ~ [\d]+
mac ~ [a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]
interface ~ [\w]+
signature ::= signature_item+ separator => [;]
signature_item ::= signature_item_name '=' signature_item_value
signature_item_name ~ [\w\.]+
signature_item_value ::= ip | mac
dict ::= '<dictionary>' '{' pairs '}'
array ::= '<array>' '{' items '}'
items ::= item+
item ::= index ':' value
index ~ [\d]+
:discard ~ whitespace
whitespace ~ [\s]+
END_OF_SOURCE
} );
my $input = <<EOI;
scutil
> open
> show State:/Network/Service/0F70B221-EEF7-4ACC-96D8-ECBA3A15F132/IPv4
<dictionary> {
ARPResolvedHardwareAddress : 00:1b:c0:4a:82:f9
ARPResolvedIPAddress : 10.10.0.254
AdditionalRoutes : <array> {
0 : <dictionary> {
DestinationAddress : 10.10.0.146
SubnetMask : 255.255.255.255
}
1 : <dictionary> {
DestinationAddress : 169.254.0.0
SubnetMask : 255.255.0.0
}
}
Addresses : <array> {
0 : 10.10.0.146
}
ConfirmedInterfaceName : en0
InterfaceName : en0
NetworkSignature : IPv4.Router=10.10.0.254;IPv4.RouterHardwareAddress=00:1b:c0:4a:82:f9
Router : 10.10.0.254
SubnetMasks : <array> {
0 : 255.255.255.0
}
}
EOI
say Dumper $g->parse( \$input, { trace_terminals => 0 } );
Run Code Online (Sandbox Code Playgroud)
输出:
use 5.010;
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Terse = 1;
$Data::Dumper::Deepcopy = 1;
use Marpa::R2;
my $g = Marpa::R2::Scanless::G->new( { source => \(<<'END_OF_SOURCE'),
:default ::= action => [ name, value]
lexeme default = action => [ name, value] latm => 1
scutil ::= 'scutil' '> open' '> show' path '<dictionary>' '{' pairs '}'
path ~ [\w/:\-]+
pairs ::= pair+
pair ::= name ':' value
name ~ [\w]+
value ::= ip | mac | interface | signature | array | dict
ip ~ octet '.' octet '.' octet '.' octet
octet ~ [\d]+
mac ~ [a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]':'[a-z0-9][a-z0-9]
interface ~ [\w]+
signature ::= signature_item+ separator => [;]
signature_item ::= signature_item_name '=' signature_item_value
signature_item_name ~ [\w\.]+
signature_item_value ::= ip | mac
dict ::= '<dictionary>' '{' pairs '}'
array ::= '<array>' '{' items '}'
items ::= item+
item ::= index ':' value
index ~ [\d]+
:discard ~ whitespace
whitespace ~ [\s]+
END_OF_SOURCE
} );
my $input = <<EOI;
scutil
> open
> show State:/Network/Service/0F70B221-EEF7-4ACC-96D8-ECBA3A15F132/IPv4
<dictionary> {
ARPResolvedHardwareAddress : 00:1b:c0:4a:82:f9
ARPResolvedIPAddress : 10.10.0.254
AdditionalRoutes : <array> {
0 : <dictionary> {
DestinationAddress : 10.10.0.146
SubnetMask : 255.255.255.255
}
1 : <dictionary> {
DestinationAddress : 169.254.0.0
SubnetMask : 255.255.0.0
}
}
Addresses : <array> {
0 : 10.10.0.146
}
ConfirmedInterfaceName : en0
InterfaceName : en0
NetworkSignature : IPv4.Router=10.10.0.254;IPv4.RouterHardwareAddress=00:1b:c0:4a:82:f9
Router : 10.10.0.254
SubnetMasks : <array> {
0 : 255.255.255.0
}
}
EOI
say Dumper $g->parse( \$input, { trace_terminals => 0 } );
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
240 次 |
| 最近记录: |