use Data::Peek; my %d; while () { s/^\s*>?\s*(.*?)[\s\r\n]*\z/$1/; m/^(\d+)$/ ? push @{$d{$a}} => $1 : ($a = $_); } DDumper \%d; __END__ >James >40 >James >35 >James >26 >James >15 James 10 >12 >Philip 10 4 >5 Philip James Philip 18 #### { James => [ '40', '35', '26', '15', '10', '12' ], Philip => [ '10', '4', '5', '18' ] }