in reply to Negative Lookahead Assertion Problem

Surely trying to match \s* is futile in a negative-lookup? Because \s* can match nothing it will always succeed, thereby never matching?? I tried using \s+.

The following code:

#!/usr/bin/perl -w use strict; my @strings = ( "Foo::Bar()", "Foo::Bar ()", "Foo::Bar ()", " Foo::Bar()", " Foo::Bar ()" ); my %test = ( 1 => qr/Foo::Bar(?!\s*\()/, 2 => qr/Foo::Bar(?!\s+\()/ );
foreach my $teststring ( @strings ) { print( "---$teststring---\n" ); foreach my $testnum ( sort { $a <=> $b } keys %test ) { if ( $teststring =~ m/$test{$testnum}/ ) { print( "test $testnum matches\n" ); } else { print( "test $testnum does not match\n" ); } } }
produces the following output
---Foo::Bar()--- test 1 does not match test 2 matches ---Foo::Bar ()--- test 1 does not match test 2 does not match ---Foo::Bar ()--- test 1 does not match test 2 does not match --- Foo::Bar()--- test 1 does not match test 2 matches --- Foo::Bar ()--- test 1 does not match test 2 does not match

Replies are listed 'Best First'.
Re^2: Negative Lookahead Assertion Problem
by ysth (Canon) on Jul 19, 2005 at 06:25 UTC
    You missed the literal ( after the \s*. Together, \s*( does specify a meaningful assertion. In your tests, all your sample data is supposed to not match by my understanding of the OP. Only something such as "Foo::Bar is my favorite module" should match.
      I'm confused by your post. Breaking down qr/Foo::Bar(?!\s+\()/ we get:
      Foo::Bar # literal 'Foo::Bar' (?! # start of negative look-ahead \s+ # one or more white space chars \( # literal opening bracket ) # end of negative look-ahead
      so to answer your reply, I believe I provided the literal ( after the \s*.

      To answer your other statement, that something such as "Foo::Bar is my favourite module" should match, I agree - that is how I read the initial requirement from the thread. In which case my answer of using \s+ kept within the spirit of the original statements made by the thread author. However I wanted to keep my example in line with the example that the author had tried, hence the use of the literal (. Hope this clears up my answer.

        My point was that only something like "Foo::Bar is my favorite module" should match, not "Foo::Bar()" and " Foo::Bar()" (which changing * to + make match).

        As to "missing )", I meant (but put it poorly) in your statement:

        Surely trying to match \s* is futile in a negative-lookup? Because \s* can match nothing it will always succeed, thereby never matching??
        The assertion wasn't \s*, it was \s*\(, a horse of a completely different color.
Re^2: Negative Lookahead Assertion Problem
by Limbic~Region (Chancellor) on Jul 19, 2005 at 14:07 UTC
    monarch,
    I have to agree with ysth. The \s* is not meaningless because it is followed immediately by a literal (which is what his comment was referring to). To be a complete match it has to match 0 or more whitespaces and an open paren. In your solution there has to be at least 1 space - which doesn't fit the bill.

    Cheers - L~R