/foo(.*?)(foo|bar)/ && "bar" ne $2
####
/foo(.*?)foo/ && $1 !~ /bar/
####
Benchmark: running japhy, obvious, tilly, and tye,
each for at least 3 CPU seconds (sorted fastest to slowest)...
obvious: 3.13 CPU @ 77.96/s (n=244)
tilly: 3.41 CPU @ 33.43/s (n=114)
tye: 3.29 CPU @ 20.06/s (n=66)
japhy: 3.02 CPU @ 10.60/s (n=32)
####
#!/usr/bin/perl -w
use strict;
use Benchmark;
my @pat= qw( fooxfoo fooxbar xfooxfoo xfooxbar
fooxfoox fooxbarx xfooxfoox xfooxbarx );
my @fill= ( "ba", "fo", "bf", "bafo", "babrar" );
@pat= map { my $fill= $_ x 1000; map { ( my $pat= $_ ) =~ s/x/$fill/g; $pat } @pat } @fill;
sub obvious {
/foo(.*?)foo/ && $1 !~ /bar/
and $1
}
sub tye {
/foo(.*?)(bar|foo)/ && "bar" ne $2
and $1
}
sub tilly {
/foo((?:(?!bar).)*)foo/
and $1
}
sub japhy {
m{
foo
( # save to $1
[^b]* # 0 or more non-b characters
(?:
(?>b+) # 1 or more b's (NO BACKTRACKING!)
(?:
a(?!r) # an 'a' NOT followed by an 'r'
| # or
[^a] # a non-a character
)
[^b]* # 0 or more non-b characters
)* # that whole b... subset, 0 or more times
)
foo # and foo
}x
and $1
}
sub checkthese {
my( $sub, $hTests )= @_;
my %res;
for my $meth ( keys %$hTests ) {
my $res= $sub->( $hTests->{$meth} );
for( keys %res ) {
if( $res ne $res{$_} ) {
warn "$meth and $_ disagree!\n";
}
}
$res{$meth}= $res;
}
}
checkthese( sub { join " ", map { $_[0]->() } @pat }, {
tilly => \&tilly,
japhy => \&japhy,
tye => \&tye,
obvious => \&obvious,
} );
timethese( -3, {
obvious => sub { map obvious(), @pat },
tye => sub { map tye(), @pat },
tilly => sub { map tilly(), @pat },
japhy => sub { map japhy(), @pat },
} );