#!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; use 5.010; #~ use v5.10.0; my $raw = 'config system interface edit "dmz" set vdom "root" set ip 192.18.254.1 255.255.254.0 set allowaccess ping fgfm set type physical set alias "Guest-Wlan" next edit "wan2" set vdom "test" set ip 10.4.254.198 255.255.255.252 set allowaccess ping https ssh snmp set type physical set alias "To MON ospf int" next edit "wan1" set vdom "root" set ip 1.1.1.1 255.255.255.252 set allowaccess ping https set type physical set alias "To Internet" next edit "modem" set vdom "root" set mode pppoe set allowaccess fgfm set type physical next edit "ssl.root" set vdom "root" set type tunnel next edit "ssl.MyRealm" set vdom "MyRealm" set type tunnel next edit "internal1" set vdom "root" set ip 10.1.16.3 255.255.255.0 set allowaccess ping https ssh snmp fgfm set type physical set alias "To MON Internal " next edit "internal2" set vdom "MyRealm" set dhcp-relay-service enable set dhcp-relay-ip "192.168.1.1" set ip 192.168.2.1 255.255.254.0 set allowaccess ping https ssh snmp fgfm set type physical set alias "To MINE" next edit "VPN-Dial" set vdom "root" set type tunnel set interface "wan1" next end '; 0 and $raw = 'config system interface edit "dmz" set vdom "root" set ip 192.18.254.1 255.255.254.0 set allowaccess ping fgfm set type physical set alias "Guest-Wlan" next end '; #### my $FROM_CONFIG = qr{ (? ^ \s* config (? [^\r\n]+ ) [\r\n]+ ) | (? ^ \s* (?:end|next) \s* [\r\n]+ ) | (? ^ \s* (?i:edit) \s* "(? [^"]+ )" \s* [\r\n]+ ) | (? ^ \s* (?i:set) \s+ #~ (? \w+ ) (? \w+ ) \s+ #~ "(? [^"]+ )" #~ \s* (? [^\r\n]++ ) [\r\n]+ ) | (? . ) }xms; my @stack = {}; while( $raw =~ m{$FROM_CONFIG}g ){ my $freeze = { %+ }; #~ dd( $freeze ); if( $freeze->{config} ){ my $new = {}; $stack[-1]->{ $freeze->{config_name} } = $new; push @stack, $new; }elsif( $freeze->{edit} ){ my $new = {}; $stack[-1]->{ $freeze->{edit_quoted} } = $new; push @stack, $new; }elsif( $freeze->{set} ){ $stack[-1]->{ $freeze->{type} } = $freeze->{val}; }elsif( $freeze->{closer} ){ pop @stack; } } dd( \@stack ); __END__ #### __END__ __END__ [ { " system interface" => { "dmz" => { alias => "\"Guest-Wlan\"", allowaccess => "ping fgfm", ip => "192.18.254.1 255.255.254.0", type => "physical", vdom => "\"root\"", }, "internal1" => { alias => "\"To MON Internal \"", allowaccess => "ping https ssh snmp fgfm", ip => "10.1.16.3 255.255.255.0", type => "physical", vdom => "\"root\"", }, "internal2" => { alias => "\"To MINE\"", allowaccess => "ping https ssh snmp fgfm", ip => "192.168.2.1 255.255.254.0", type => "physical", vdom => "\"MyRealm\"", }, "modem" => { allowaccess => "fgfm", mode => "pppoe", type => "physical", vdom => "\"root\"", }, "ssl.MyRealm" => { type => "tunnel", vdom => "\"MyRealm\"" }, "ssl.root" => { type => "tunnel", vdom => "\"root\"" }, "VPN-Dial" => { interface => "\"wan1\"", type => "tunnel", vdom => "\"root\"" }, "wan1" => { alias => "\"To Internet\"", allowaccess => "ping https", ip => "1.1.1.1 255.255.255.252", type => "physical", vdom => "\"root\"", }, "wan2" => { alias => "\"To MON ospf int\"", allowaccess => "ping https ssh snmp", ip => "10.4.254.198 255.255.255.252", type => "physical", vdom => "\"test\"", }, }, }, ]