use strict; use warnings; use 5.010; use re 'eval'; my %h = ( '^foo' => sub { say 'foo' }, '^bar' => sub { say 'bar' }, ); my $what; my $re = join '|', map { "$_(?{\$what = '$_'})" } keys %h; if ('foo' =~ m/$re/o) { $h{$what}->(); }