m{ ^ # start of the string FOO ( # this will become $1 (?! # must not be BA[RZ]$ # BAR or BAZ followed by end-of-string ) .* # now anything else (except "\n") # no need to "$", because ".*" will happily swallow it all ) }x #### $ perl -MData::Dumper -le '%h = map { $_ => /^FOO((?!BA[RZ]$).*)/ ? $1 : q(does NOT match) } qw/FOO FOOZIM FOOBAR FOOA FOOBAZ FOOBARX/; $Data::Dumper::Terse = $Data::Dumper::Indent = 1; print Dumper \%h' { 'FOOBAR' => 'does NOT match', 'FOOZIM' => 'ZIM', 'FOOA' => 'A', 'FOOBARX' => 'BARX', 'FOOBAZ' => 'does NOT match', 'FOO' => '' }