#!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; use 5.010; #~ use v5.10.0; my $raw = "\nbob { \n ed { \n larry { \n rule5 { \n option { \n disable-server-response-inspection no; \n } \n tag [ some_tag ]; \n from [ prod-L3 ]; \n to [ corp-L3 ]; \n source [ any ]; \n destination [ any ]; \n source-user [ any ]; \n category [ any ]; \n application [ any ]; \n service [ any ]; \n hip-profiles [ any ]; \n log-start no; \n log-end yes; \n negate-source no; \n negate-destination no; \n action allow; \n log-setting orion_log; \n }\n rule6 { \n option { \n disable-server-response-inspection no; \n } \n tag [ some_tag ]; \n from [ prod-L3 ]; \n to [ corp-L3 ]; \n source [ any ]; \n destination [ any ]; \n source-user [ any ]; \n category [ any ]; \n application [ any ]; \n service [ any ]; \n hip-profiles [ any ]; \n log-start no; \n log-end yes; \n negate-source no; \n negate-destination no; \n action allow; \n log-setting orion_log; \n } \n }\n }\n}\n"; ;;;;;;;;; my $FROM_CONFIG = do { use Regexp::Grammars 1.038; qr{ # Switch off context substring retention aka $MATCH{""} <[Object]> (?{ #~ ::dd( -Objects => \%MATCH ); $MATCH = $MATCH{Object}; }) \{ <[Value]>* \} (?{ #~ ::dd( -Object => \%MATCH ); $MATCH = { $MATCH{Name} => { map { %$_ } @{$MATCH{Value}} } }; }) | [\w\-]+ [^\r\n\{;]+ ^ \s* \s+ ; \s*? [\r\n]+ (?{ #~ ::dd(-KeyVal,\%MATCH); $MATCH = { $MATCH{Key} => $MATCH{Val} }; }) }xms; };;;;;; if( $raw =~ $FROM_CONFIG ){ dd(\%/) ; #/ } else { print "## fail to match \n"; } __END__ { Objects => [ { bob => { ed => { larry => { rule5 => { "action" => "allow", "application" => "[ any ]", "category" => "[ any ]", "destination" => "[ any ]", "from" => "[ prod-L3 ]", "hip-profiles" => "[ any ]", "log-end" => "yes", "log-setting" => "orion_log", "log-start" => "no", "negate-destination" => "no", "negate-source" => "no", "option" => { "disable-server-response-inspection" => "no" }, "service" => "[ any ]", "source" => "[ any ]", "source-user" => "[ any ]", "tag" => "[ some_tag ]", "to" => "[ corp-L3 ]", }, rule6 => { "action" => "allow", "application" => "[ any ]", "category" => "[ any ]", "destination" => "[ any ]", "from" => "[ prod-L3 ]", "hip-profiles" => "[ any ]", "log-end" => "yes", "log-setting" => "orion_log", "log-start" => "no", "negate-destination" => "no", "negate-source" => "no", "option" => { "disable-server-response-inspection" => "no" }, "service" => "[ any ]", "source" => "[ any ]", "source-user" => "[ any ]", "tag" => "[ some_tag ]", "to" => "[ corp-L3 ]", }, }, }, }, }, ], }