Narek
Narek

Reputation: 3823

Preg_match exclude word from text

I have string:

FirstWord word2 word3 wrongWord word4 lastWord

Want to select string starts with FirstWord, ends with lastWord and doesn't contain wrongWord.

For first and last I have:

/firstword (.*?) lastword/i

but excluding wrongword didn't work.

Tried:

/firstword (^wrongWord*?) lastword/i

/firstword ^((?!wrongWord).)* lastword/i

and more like this, but nothing works.

Upvotes: 5

Views: 10123

Answers (4)

Alan Moore
Alan Moore

Reputation: 75222

What if the forbidden word happens to be part of a longer word? For example, what if you want strings that start with "first" and end with "last" but don't contain the word "word"? For example:

"first one two word last"              # don't match
"first three wordplay four last"       # OK
"first five swordfish six seven last"  # OK

Adapting the accepted answer would give you this:

/^first (?:(?!word).)+ last$/i

...but that would reject all three strings. There's no need to perform the lookahead at every position anyway. Just do it once at the beginning of each word:

/^first(?:\s+(?!word\b)\w+)*\s+last$/i

See live demo

Upvotes: 1

hwnd
hwnd

Reputation: 70722

What's wrong with simply the following?

/^firstword ((?:(?!wrongword).)+) lastword$/i

See live demo

Regular expression:

^              the beginning of the string
 firstword     'firstword '
 (             group and capture to \1:
  (?:          group, but do not capture (1 or more times)
   (?!         look ahead to see if there is not:
    wrongword  'wrongword'
   )           end of look-ahead
   .           any character except \n
  )+           end of grouping
 )             end of \1
 lastword      ' lastword'
$              before an optional \n, and the end of the string

Upvotes: 9

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

You can use this trick:

/^firstword ((?:[^w]+?|\Bw|w(?!rongword\b))*?) lastword$/i

or more efficient:

/^firstword ((?>[^w\s]++|\s(?!lastword$)|\Bw|w(?!rongword\b))*+) lastword$/i

Upvotes: 2

KeyNone
KeyNone

Reputation: 9150

See this example.

The regex used is

/firstword((?!wrongword).)*lastword/i

Upvotes: 2

Related Questions