#!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=317376 use warnings; local $_ = <<''; BEGIN:VCARD FN:Fee AGENT: BEGIN:VCARD FN:Fie AGENT: BEGIN:VCARD FN:Foe AGENT: BEGIN:VCARD FN:Fum END:VCARD END:VCARD END:VCARD END:VCARD sub error { substr $_, pos($_) || 0, 0, "\e\[1;31;43m @_ \e[m"; die $_,"\n"; } my %card = parse(); /\G\z/gc or error 'incomplete parse'; use Data::Dumper; print Dumper \%card; print "\nwhat was wanted: $card{AGENT}{AGENT}{AGENT}{FN}\n"; sub parse { my %h; /\GBEGIN:VCARD\n/gc ? 'ignore' : /\GEND:VCARD\n/gc ? return %h : /\G(\w+):\n/gc ? ($h{$1} = { parse() }) : /\G(\w+):(.+)\n/gc ? ($h{$1} = $2) : error 'syntax' while 1; } #### $VAR1 = { 'FN' => 'Fee', 'AGENT' => { 'FN' => 'Fie', 'AGENT' => { 'FN' => 'Foe', 'AGENT' => { 'FN' => 'Fum' } } } }; what was wanted: Fum