Page 1 of 1

Trouble with negative look ahead

Posted: Sat Oct 03, 2009 3:58 pm
by thegodfaza
I'm having trouble getting a regex to fail when it hits a specific word. It's easier to show examples than explain it.
Here is the outcome I want to achieve:
It has to match "Title.Of.Item" but not "Fail". Note that "Fail", "Title.Of.Item", and "Possible.Text" are only placeholders; Possible text can be anything including nothing at all; And words may be seperated by spaces or periods.

Code: Select all

Title.Of.Item.Possible.Text.Fail.Possible.Text -- Fail
Title Of Item Possible Text Fail Possible Text -- Fail
Another.Item.Possible.Text.Fail.Possible.Text -- Fail
Another.Item.Possible.Text.Possible.Text -- Fail
Title.Of.Item.Possible.Text.Possible.Text -- Pass
Title Of Item Possible Text Possible Text -- Pass
 
I've tried several different regex's and none work. For example:

Code: Select all

^(Title.Of.Item.*(?!Fail).*)$ fails on everything.
I'm using the expression in a program which searches through an unordered list. When it finds a match it marks the line.

Re: Trouble with negative look ahead

Posted: Sat Oct 03, 2009 7:34 pm
by requinix
You have to apply the lookahead to every character being repeated. Basically

Code: Select all

(?!Fail).(?!Fail).(?!Fail).(?!Fail). ...

Code: Select all

(?!Fail).*
That looks for a Fail and when it doesn't find anything, goes to the end of the string. All it does is check that the substring doesn't begin with "Fail" - which isn't what you want.

Code: Select all

((?!Fail).)*
That will repeat (?!Fail). until the end of the string. It checks for a "Fail", reads in a character, then checks for another "Fail", reads in another character, and so on.

What would be much more efficient - if "Fail" is a static string with no regex power - is if you used regular string functions to check for "Fail" rather than make the regex do the work.

Re: Trouble with negative look ahead

Posted: Sun Oct 04, 2009 1:16 am
by prometheuzz
Try:

Code: Select all

$tests = array(
  'Title.Of.Item.Possible.Text.Fail.Possible.Text',
  'Title Of Item Possible Text Fail Possible Text',
  'Another.Item.Possible.Text.Fail.Possible.Text',
  'Another.Item.Possible.Text.Possible.Text',
  'Title.Of.Item.Possible.Text.Possible.Text',
  'Title Of Item Possible Text Possible Text'
);
foreach($tests as $t) {
  if(preg_match('/^Title\.Of\.Item(?!.*Fail).*$/', $t)) {
    echo $t . "\n";
  }
}
(not properly tested!)

Edit:

Escaped the DOT's after jackpf's post.

Re: Trouble with negative look ahead

Posted: Sun Oct 04, 2009 2:21 am
by jackpf
Shouldn't you escape those periods (full stops)?

Re: Trouble with negative look ahead

Posted: Sun Oct 04, 2009 2:26 am
by prometheuzz
jackpf wrote:Shouldn't you escape those periods (full stops)?
Yes, silly me: I simply copy-pasted a part of the OP's regex...
Thanks.

Re: Trouble with negative look ahead

Posted: Mon Oct 05, 2009 11:26 am
by prometheuzz
pankajnagarkoti80 wrote:I'm having trouble getting a regex to fail when it hits a specific word.
I'm having trouble with people posting random posts just to advertise their website.

Re: Trouble with negative look ahead

Posted: Mon Oct 05, 2009 12:36 pm
by jackpf
Report them :) T'is what I do...

I'm sure the mods are sick of me by now.

Re: Trouble with negative look ahead

Posted: Mon Oct 05, 2009 12:40 pm
by prometheuzz
jackpf wrote:Report them :) T'is what I do...

I'm sure the mods are sick of me by now.
Yes, I was planning to do that. I gave pankajnagarkoti80 a bit time, perhaps s/he actually had a problem with regex, but it seems s/he truly is a spammer.

Re: Trouble with negative look ahead

Posted: Mon Oct 05, 2009 1:15 pm
by jackpf
Yeah. It's funnier when they post such a general post that could almost fit...but the excessive links to hosting services, or pharmaceutical products gives it away.

I think there was one in the "Introduce yourself" thread like...
Yeah, I love your post.

[spam link] [spam link] [spam link]
In the end they're only wasting their own time.