我希望在开头和结尾匹配同一组的字符串,但不要在模式中重复组。
为简单起见,我举一个例子
我们假设组是一个数字,它出现在字符串的开头和结尾。我想匹配123
和567
,但前提是它们被...
隔开。
123...567
一个明显的正则表达式是:
/([0-9]{3})...([0-9]{3})/
我想避免在我的正则表达式中写两次[0-9]{3}
。原因是,在我的应用程序中,模式比简单数字复杂得多。 [0-9]{3}
实际上是一个长约100个字符的模式。我想避免重复它以减少可能的错误。
我已经阅读了递归模式,但它似乎与我的用例不符。
所以问题是:我是否以及如何重写上述模式以避免我的第一组冗余?
答案 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