use Data::Dumper; my $string = "one 1 two 2 three 3 odd"; my %hash = $string =~ / (\w+) # one captured word (?: # followed by \s(\d+) # a space and a captured number )? # in an optional non capturing group /gx; print Dumper \%hash; __DATA__ $VAR1 = { 'three' => '3', 'two' => '2', 'one' => '1', 'odd' => undef };