Here is another alternative:

/foo(.*?)(foo|bar)/ && "bar" ne $2

One functional difference between this and tilly's and japhy's correct solutions is that it can clobber regex variables when the first half matches but the total expression is false. Another is that you can't embed it inside a larger regex.

Which leads me to the "obvious" solution:

/foo(.*?)foo/ && $1 !~ /bar/

And after benchmarking the results are:

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)

So the most "optimized" is the slowest and the most obvious is the fastest. I think I know which one I'll use next time. :) Here is the benchmarking code:

#!/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 }, } );
        - tye (but my friends call me "Tye")

In reply to Be obvious (Re: Regex'ing backreferences) by tye
in thread Regex'ing backreferences by Uruk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.