#! perl -sl use strict; use Data::Dump qw[ pp ]; sub parseConfig { my( $source, %config ) = shift; $source =~ s<(\S+)\s*(\{)\s*(.+)\}|(\S+)(\s+)([^;]+);> < my( $key, $f, $rest ) = ( $1 || $4, $2 || $5, $3 || $6 ); $config{ $key } = $f eq "{" ? parseConfig( $rest ) : $rest; >seg; return \%config; } my $config = parseConfig( do{ local $/; } ); pp $config; __DATA__ ## data per your OP #### C:\test>junk70 { 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 ", }, }, }, }, }