Reputation: 3823
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
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
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
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
Reputation: 9150
See this example.
The regex used is
/firstword((?!wrongword).)*lastword/i
Upvotes: 2