Given that they are constant strings that you are checking then your performance will be better splitting the test into three parts, substr to check for the start and end strings and index to check for the absence of the middle string. This is some benchmarking I did.
#!/net/perl/5.10.0/bin/perl
use strict;
use warnings;
use Benchmark qw(cmpthese);
my $str1 = join '', 'a' .. 'z';
my $str2 = join '', 'a' .. 'l', 'baz', 'm' .. 'z';
my $str3 = join '', 'a' .. 'z', 'a';
my $rx = qr/\Aabc(?!.*baz).*xyz\z/ms;
cmpthese(
-1,
{
regex_match => sub { $str1 =~ /$rx/ },
index_match => sub {
substr( $str1, 0, 3 ) eq 'abc'
&& substr( $str1, -3 ) eq 'xyz'
&& index( $str1, 'baz' ) == -1;
},
}
);
cmpthese(
-1,
{
regex_fail1 => sub { $str2 =~ /$rx/ },
index_fail1 => sub {
substr( $str2, 0, 3 ) eq 'abc'
&& substr( $str2, -3 ) eq 'xyz'
&& index( $str2, 'baz' ) == -1;
},
}
);
cmpthese(
-1,
{
regex_fail2 => sub { $str3 =~ /$rx/ },
index_fail2 => sub {
substr( $str3, 0, 3 ) eq 'abc'
&& substr( $str3, -3 ) eq 'xyz'
&& index( $str3, 'baz' ) == -1;
},
}
);
__END__
Rate regex_match index_match
regex_match 337317/s -- -73%
index_match 1228799/s 264% --
Rate regex_fail1 index_fail1
regex_fail1 362337/s -- -70%
index_fail1 1226609/s 239% --
Rate regex_fail2 index_fail2
regex_fail2 865569/s -- -48%
index_fail2 1653160/s 91% --