再次匹配组而不再粘贴它(例如ABA)

时间:2015-07-01 12:52:52

标签: regex pcre

我希望在开头和结尾匹配同一组的字符串,但不要在模式中重复

为简单起见,我举一个例子

我们假设是一个数字,它出现在字符串的开头和结尾。我想匹配123567,但前提是它们被...隔开。

123...567

一个明显的正则表达式是:

/([0-9]{3})...([0-9]{3})/

我想避免在我的正则表达式中写两次[0-9]{3}。原因是,在我的应用程序中,模式比简单数字复杂得多。 [0-9]{3}实际上是一个长约100个字符的模式。我想避免重复它以减少可能的错误。

我已经阅读了递归模式,但它似乎与我的用例不符。

所以问题是:我是否以及如何重写上述模式以避免我的第一组冗余?

1 个答案:

答案 0 :(得分:2)

基本上,您可以使用其编号引用子模式(捕获组):

/([0-9]{3})...((?1))/ 
# or
/([0-9]{3})...(\g<1>)/ # oniguruma syntax

或者你也可以使用相对参考:

/([0-9]{3})...(?-1)/ # -1 means the last opened capture group on the left
/([0-9]{3})...\g<-1>/ # (oniguruma)
# or if there's an other opened capture group:

/([0-9]{3})...((?-2))/

当你有一个包含多个子模式的长模式时,使用命名捕获可能更方便:

/(?<mycap>[0-9]{3})...(\g<mycap>)/

当你有一个更复杂的模式时,你可以包含一个定义部分,其中子模式被定义(作为一种词法分析器),在&#34; real&#34;之前。主要模式:

/ # subpattern definitions:
 (?(DEFINE)
    (?<mycap>[0-9]{3})
    (?<anothersubpattern> [A-Z]{2,4}:[0-9]{4} )
    etc.
 )

  # main pattern
(\g<mycap>) ... (\g<mycap>)
/x

注意:php接受几种语法来引用子模式:\g<mycap>(?&mycap)是等效的。以同样的方式,您可以定义具有不同语法的命名子模式:(?<mycap> ...)(?'mycap' ...)(?P<mycap> ...)

为避免混淆:

(?1), (?-1), \g<1>, \g<-1>, (?&mycap), \g<mycap> refer to subpatterns

\1, \g{1}, \g{-1}, \k<mycap>, \g{mycap} refer to captured content