my $remains = $string; my %parsed = (); while ( $remains =~ /^\s*\<(.*)$/ ) { # for each tag... $remains = $1; #we expect an identifier ( $remains =~ /^\s*(\w+)(.*)$/ ) or die 'expected identifier'; my $kwd = $1; $remains = $2; if ( $kwd eq 'vertical' ) { ( $remains =~ /^\s*(\w+)\s*\=\s*(\w+)(.*)$/ or die 'expected assignment'; $parsed{ $kwd } and die 'duplicate definition'; $parsed{ $kwd }{ $1 } = $2; $remains = $2; Exhausted( \$remains ); next; # next tag } if ... # next tag processor goes here }