use strict; use warnings; use Data::Dump qw( dump ); my $data = do{local $/;}; my @people_educations; while( $data =~ m/(.*?)<\/person>/gis ) { my $one_persons_info = $1; while( $one_persons_info =~ m/(.*?)<\/education>/gis ) { my $this_guys_education_details_string = $1 ; my %this_guys_education_details_hash ; my @this_guys_education_sections ; while( $this_guys_education_details_string =~ /<([^\/]*?)>/gis ) { push @this_guys_education_sections, $1 ; } foreach my $single_section ( @this_guys_education_sections ) { if( $this_guys_education_details_string =~ /<$single_section>(.*?)<\/$single_section>/gis ) { $this_guys_education_details_hash{ $single_section } = $1; } } push @people_educations, \%this_guys_education_details_hash; } } dump( \@people_educations ); __DATA__
xxx xxx
xxx xxx
xxx xxx
xxx xxx ggg
xxx xxx
xxx
#### [ { Degree => "xxx", Major => "xxx" }, { Degree => "xxx", Grade => " ggg ", Minor => "xxx" }, { Degree => "xxx" }, ]