Regex – Find all matching words that don’t begin with a specific prefix

Off the top of my head, you could try:

\b             # word boundary - matches start of word
(?!girl)       # negative lookahead for literal 'girl'
\w*            # zero or more letters, numbers, or underscores
friend         # literal 'friend'
\b             # word boundary - matches end of word

Update

Here’s another non-obvious approach which should work in any modern implementation of regular expressions:

Assuming you wish to extract a pattern which appears within multiple contexts but you only want to match if it appears in a specific context, you can use an alteration where you first specify what you don’t want and then capture what you do.

So, using your example, to extract all of the words that either are or end in friend except girlfriend, you’d use:

\b               # word boundary
(?:              # start of non-capture group 
  girlfriend     # literal (note 1)
|                # alternation
  (              # start of capture group #1 (note 2)
    \w*          # zero or more word chars [a-zA-Z_]
    friend       # literal 
  )              # end of capture group #1
)                # end of non-capture group
\b

Notes:

  1. This is what we do not wish to capture.
  2. And this is what we do wish to capture.

Which can be described as:

  • for all words
  • first, match ‘girlfriend’ and do not capture (discard)
  • then match any word that is or ends in ‘friend’ and capture it

In Javascript:

const target="A boyfriend and girlfriend gained a friend when they asked to befriend them";

const pattern = /\b(?:girlfriend|(\w*friend))\b/g;

let result = [];
let arr;

while((arr=pattern.exec(target)) !== null){
  if(arr[1]) {
    result.push(arr[1]);
  }
}

console.log(result);

which, when run, will print:

[ 'boyfriend', 'friend', 'befriend' ]

Leave a Comment