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

Match group again without pasting it again (eg. ABA)

我想匹配一个字符串,该字符串在开头和结尾具有 相同的组 ,但不重复 模式。

为简单起见,我举个例子

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

分隔

123...567

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

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

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

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

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

基本上你可以用它的编号来引用一个子模式(一个捕获组):

/([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>)/

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

/ # 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

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