Подтвердить что ты не робот

Regex - найти все совпадающие слова, которые не начинаются с определенного префикса

Как мне создать регулярное выражение, чтобы найти все слова, которые заканчиваются в строке, но не начинаться со строки?

например. Найдите все слова, которые заканчиваются в "другом", которые не начинаются со слова "девушка" в следующем предложении:

"Друг и подруга получили друга, когда они попросили подружиться их

Элементы в жирный должны совпадать. Слово "подруга" не должно быть.

4b9b3361

Ответ 1

Сверху моей головы вы можете попробовать:

\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

Примечания:

  • Это то, что мы не делаем, чтобы захватить.
  • И это то, что мы делаем, чтобы захватить.

Что можно охарактеризовать как:

  • для всех слов
  • во-первых, сопоставить "подругу" и не захватывать (отбрасывать)
  • затем сопоставить любое слово, которое заканчивается "другом" или заканчивается, и захватывать его

В 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' ]

Ответ 2

Попробуйте следующее:

/\b(?!girl)\w*friend\b/ig

Ответ 3

Это может работать:

\w*(?<!girl)friend

вы также можете попробовать

\w*(?<!girl)friend\w*, если вы хотите совместить слова типа befriended или boyfriends.

Я не уверен, что ?<! доступен во всех версиях регулярных выражений, но это выражение работало в Expersso (которое я считаю .NET).

Ответ 4

Я изменил Rob Raisch на регулярное выражение, которое находит слова, содержащие определенную подстроку, но не содержащую другую определенную подстроку

\b(?![\w_]*Unwanted[\w_]*)[\w_]*Desired[\w_]*\b

Итак, например, \b (?! [\ w _] * mon [\ w _] *) [\ w _] * день [\ w _] *\b найдет каждое слово с "днем" (например, днем, вторник, днем), кроме случаев, когда оно также содержит "mon" (например, понедельник)

Может быть, полезно для кого-то.