In your code there is the unrelated problem, in that $search4 is not a reqex.
$search4 =~ qw/.*?_.*?/;
means that you are matching the undefined variable $search4 against qw/.*?_.*?/;. qw is basically splitting a string on whitespace. In this case there is no whitespace and thus you are matching against the string .*?_.*?. In void context this has no effect at all, $search4is left undefined.
With use strict; use warnings; and after declaring your variables you would have gotten an appropriate error.
$ cat t1.pl
use strict;
use warnings;
my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = "Joe";
my $search2 = "Hello";
my $search3 = "Jim";
my $search4 =~ qw/.*?_.*?/;
my %index;
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};
my $index4 = $index{$search4};
print $index,",",$index2,",",$index3,",",$index4, "\n";
$ perl t.pl
Use of uninitialized value $search4 in pattern match (m//) at t.pl line 8.
Use of uninitialized value $search4 in hash element at t.pl line 15.
Use of uninitialized value $index4 in print at t.pl line 16.
0,3,1,
I assume that you meant $search4 = qr/.*?_.*?/.
One solution to your problem would be to treat the regexp as a special case and to loop over your array.
$ cat t2.pl
use strict;
use warnings;
my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = 'Joe';
my $search2 = 'Hello';
my $search3 = 'Jim';
my $search4 = qr/.*?_.*?/;
my %index;
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};
# loop over the array until a match is found
my $cnt = 0;
my $index4;
for my $elem ( @array ) {
if ( $elem =~ $search4 ) {
$index4 = $cnt;
last;
}
$cnt++;
}
print "$index,$index2,$index3,$index4\n";
$ perl t2.pl
0,3,1,2
If you want to use a lookup hash, then you might like the module Tie::Hash::Regex from CPAN.
$ cat t3.pl
use strict;
use warnings;
# modules from CPAN
use Tie::Hash::Regex;
my @array = ('Joe','Jim','Jim_BOB','Hello');
my $search = "Joe";
my $search2 = "Hello";
my $search3 = "Jim";
my $search4 = qr/.*?_.*?/;
my %index;
tie %index, 'Tie::Hash::Regex';
@index{@array} = (0..$#array);
my $index = $index{$search};
my $index2 = $index{$search2};
my $index3 = $index{$search3};
my $index4 = $index{$search4};
print "$index,$index2,$index3,$index4\n";
bernhard@bernhard-Aspire-E1-572:~/devel/StackOverflow$ perl t3.pl
0,3,1,2
Beware that there are some downsides to that solution. If multiple keys are matching, than you have no guarantee which of the matching keys you will get. And if you pass a string that does not look like a regexp, it will still be considered a regexp.
qwsplits a string into a list of words, using whitespace as the delimiter. Probably not what you wanted. Also, your regex can be simplified to/_/(i.e. contains an underscore, anywhere in the string).my @array = qw(foo bar baz foo);, then$index{foo}will be 3, the index of the lastfoo.