RegExp(PCRE或Emacs):重复先前定义的组

时间:2011-09-11 09:22:04

标签: regex perl emacs pcre

RegExps是否有一种语法允许重复同一RexExp中较早出现的组定义。请注意:我想再次'复制'组定义,我对后一组的匹配不感兴趣(即“\ n”不是我想要的)。

例如:我寻找的RegExp将匹配“spamniceggs”,“eggswithspam”,“spamlovelyspam”,“eggeggspam”,但既不是“spamwithham”也不是“deliciousegg”。

可能的PCRE RegExp将是:((?:spam)|(?:egg))\ w *((?: egg)|(?:spam)) 在这种情况下和类似的情况下,避免明确重复相同的组描述(DRY)将是很好的。因此,我正在寻找具有语义的假设运算符“~n”,如下所示:应用重新应用与第n个捕获组相同的组描述。因此,示例RegExp可以表示为:(?:( ?: spam)|(?: egg))\ w * ~1

有没有办法在这方面取得成果?

2 个答案:

答案 0 :(得分:5)

中你要求的任何正则表达式实现 Emacs 都没有这样的设施,但周围的语言使它变得足够简单。在Lisp中:

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

在C中,您可以类似地在字符串中构建正则表达式,例如sprintf

修改:在PCRE中忽略了?(DEFINE)。我将其留给Emacs /一般案例。

答案 1 :(得分:4)

如果你的意思是像Perr中的qr //,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