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

У меня есть список строк. Некоторые из них имеют вид 123-...456. Переменная часть "..." может быть:

  • строка "яблоко" , за которой следует дефис, например. 123-apple-456
  • строка "банан" , за которой следует дефис, например. 123-banana-456
  • пустую строку, например. 123-456 (обратите внимание на один дефис)

Любое слово, отличное от "apple" или "banana", недействительно.

В этих трех случаях я хотел бы сопоставить "яблоко" , "банан" и "" соответственно. Обратите внимание: я никогда не хочу захватить дефис, но я всегда хочу его сопоставить. Если строка не имеет формы 123-...456, как описано выше, то совпадения не существует.

Как написать регулярное выражение для этого? Предположим, у меня есть аромат, который позволяет смотреть, смотреть, искать и не захватывать группы.


Главное наблюдение здесь состоит в том, что когда у вас есть "яблоко" или "банан" , вы также должны иметь конечный дефис, но вы не хотите его сопоставлять. И когда вы сопоставляете пустую строку, у вас не должно быть конечного дефиса. Я думаю, что регулярное выражение, которое инкапсулирует это утверждение, будет правильным.

Ответ 1

Единственный способ не захватить что-то, это использовать правила поиска:

(?<=123-)((apple|banana)(?=-456)|(?=456))

Потому что даже с не захватывающие группы (?:…) все регулярное выражение захватывает их согласованное содержимое. Но это регулярное выражение соответствует только apple или banana, если ему предшествует 123-, а затем -456 или соответствует пустой строке, если ей предшествует 123-, а затем 456.

Ответ 2

Попробуйте:

123-(?:(apple|banana|)-|)456

Это будет соответствовать apple, banana или пустой строке, а после него будут 0 или 1 дефисы. Я ошибался в том, что мне не нужна группа для захвата. Глупый я.

Ответ 3

Обновление: спасибо немцу Родригесу Эррере!

В javascript try: /123-(apple(?=-)|banana(?=-)|(?!-))-?456/

Помните, что результат в группе 1

Regular expression visualization

Демоверсия Debuggex

Ответ 4

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

/\d{3}-(?:(apple|banana)-)?\d{3}/

Ответ 5

Я изменил один из ответов (by @op1ekun):

123-(apple(?=-)|banana(?=-)|(?!-))-?456

Причина в том, что ответ @op1ekun также соответствует "123-apple456", без дефиса после яблока.

Ответ 6

Самым простым (работает для python) является '123-(apple|banana)-?456'.