С макушки головы вы можете попробовать:
\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
Обновление
Вот еще один неочевидный подход, который должен работать в любой современной реализации регулярных выражений:
Предполагая, что вы хотите извлечь шаблон, который появляется в нескольких контекстах, но вы хотите сопоставить его только в том случае, если он появляется в определенном контексте, вы можете использовать изменение, в котором вы сначала указываете, что вам не нужно, а затем фиксируете то, что делаете .
Итак, используя ваш пример, чтобы извлечь все слова, которые либо заканчиваются на friend
, либо заканчиваются на girlfriend
, вы должны использовать:
\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
Примечания:
- Это то, что мы не делаем для захвата.
- И это то, что мы делаем для захвата.
Что можно описать как:
- для всех слов
- сначала сопоставьте 'girlfriend' и не снимайте (отбрасывайте)
- затем сопоставьте любое слово, которое является или заканчивается словом «друг», и перехватите его
В 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);
который при запуске напечатает:
[ 'boyfriend', 'friend', 'befriend' ]