RegExp (PCRE или Emacs): повторение ранее определенной группы - PullRequest
2 голосов
/ 11 сентября 2011

Существует ли синтаксис для RegExps, который позволяет повторять определение группы, которое появилось ранее в том же RexExp.Обратите внимание: я хочу снова «скопировать» определение группы, меня не интересует обратная ссылка на совпадение предыдущей группы (т. Е. «\ N» - это не то, что я ищу).

Например,: Я ищу RegExp, который будет соответствовать "spamniceggs", "eggswithspam", "spamlovelyspam", "eggeggspam", но ни "spamwithham", ни "deliciousegg".

Возможный PCRE RegExp будет: ((?? Spam) | (?: Egg)) \ w * ((?: egg) | (?: Spam)) В этом и аналогичных случаях это будетхорошо, чтобы избежать явного повторения идентичного описания группы (СУХОЙ).Поэтому я ищу гипотетический оператор "~ n" со следующей семантикой: Применить повторно применить то же описание группы, что и для n-й группы захвата.Таким образом, пример RegExp может быть выражен как: (? :( ?: spam) | (?: Egg)) \ w * ~ 1

Есть ли способ достичь чего-либо в этом направлении?

Ответы [ 2 ]

5 голосов
/ 11 сентября 2011

Нет ничего подобного в любой из реализаций регулярного выражения, о которых вы спрашиваете Emacs , но окружающий язык делает это достаточно просто.В Лиспе:

(let* (s "spam")
      (e "egg")
      (sore (concat "\\(" s "\\|" e "\\)"))
      (regex (concat sore "[A-Za-z]*" sore)) )
  (... do stuff with regex ...)

В Си вы можете аналогичным образом построить регулярное выражение в строку, например, sprintf.

Редактировать : пропустил ?(DEFINE) вPCRE.Я оставляю это для дела Emacs / general.

4 голосов
/ 11 сентября 2011

Если вы имеете в виду что-то вроде qr // в Perl, у PCRE его нет, используйте? (DEFINE) и (? &). Это функции, скопированные из Perl 5.10 в PCRE. Пример для IP-адреса:

(?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
         \b (?&byte) (\.(?&byte)){3} \b
...