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__