sub dive { my $r = shift; $r = $r->{shift(@_)} while $r && @_; return $r; } my @paths = ('key1', 'key2:key22', 'key2:key23'); for my $path (@paths) { my @path = split(/:/, $path); my $val = dive(\%hash, @path); ... }