Reputation: 6926
I have this text and I want to search the word "job" except the phrase "on the job training" or a list of phrases. If I use this preg_match http://regexr.com/3dlo7
I get 3 results... but I want only the 1st and the 3rd
This is a good job and this is on the job training. Nice job
Any ideas for the preg_match?
Upvotes: 0
Views: 1202
Reputation: 6539
Use this regex:-
\bjob(?!\straining)\b
After your comment you also want to exclude word before your word then use below regex:-
\b(?<!Nice\s)job(?!\straining)\b // exclude Nice word
http://www.phpliveregex.com/p/g8h
(?<!Nice\s)job
matches Nice
"job"
that is not preceded by an "Nice "
, using negative lookbehind.
Upvotes: 0
Reputation: 89547
First, when you want to test a regex for PHP, don't use RegExr that is designed for Javascript, you can use instead regex101.com or regex.larsolavtorvik.com
You can design your pattern like this:
\bjob\b(?!(?<=\bon the job) training\b)
and if you want to exclude other cases:
\bjob\b(?!(?<=\bon the job) training\b|(?<=\bthe job) I hate\b)
You can also use a (*SKIP)(*F)
pattern (that makes the subpattern to fail and forces characters already matched to be skipped), it can be more easy to write but it's less efficient (due to the fact that the pattern has an alternation at the beginning):
\b(?:on the job training\b(*SKIP)(*F)|the job I hate\b(*SKIP)(*F)|job\b)
You can improve it a little using the first character discrimination trick to quickly fail on non-interesting positions:
\b(?=[otj])(?:on the job training\b(*SKIP)(*F)|the job I hate\b(*SKIP)(*F)|job\b)
Upvotes: 3
Reputation: 91385
How about using lookaround:
$str = 'This is a good job and this is on the job training. Nice job';
preg_match_all('/(?<!on the )\bjob\b(?! training)/', $str, $m);
print_r($m);
Output:
Array
(
[0] => Array
(
[0] => job
[1] => job
)
)
Upvotes: 1