Reputation: 179
I'm struggling with regex lookaheads and all the tutorials I can find are for password checks and not for certain character combinations.
Here's a problem I don't understand which describes my struggle with this part of regex:
$string1 = 'I have a yellow engine, I have a black engine';
$string2 = 'I have a yellow engine, I have a red engine';
$string3 = 'I have a red engine, I have a black engine';
$pattern = '~I.*?(?!.*(red|green|blue)).*?engine~';
$preg_match_all($pattern, $string[1-3], $matches);
$string1
matches correctly:
0 => "I have a yellow engine"
1 => "I have a black engine"
$string2
matches the entire string and $string3
matches similar to $string1
.
How do I design a pattern that only captures strings ('I have a [colour] engine') without certain colours?
Upvotes: 3
Views: 38
Reputation: 107347
The .*
after your negative look-ahead will match everything and actually will destroy the effect of the look-ahead. You can simply use following regex:
I\s(?:(?!(red|green|blue)).)*engine
Demo: https://regex101.com/r/tO9nC5/1
Note that you even don't need .*
inside the look-ahead, because you have a *
out of it which makes it to match every length of string.
Also note that if you want to prevent your regex to match strings like following:
I have everything I don't engine
In fact if you want to match the inner I
before engine
you better to add I
to the list of forbidden words:
I\s(?:(?!(I|red|green|blue)).)*engine
Upvotes: 2