RegEx BackReference匹配不同的值

时间:2016-08-17 09:11:48

标签: php regex pcre

我有一个正则表达式,用于匹配表单(val1 operator val2)

的表达式

这个正则表达式看起来像:

(\(\s*([a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|\*|\/|\+|\-|==|!=|>|>=|<|<=)\s*([a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*\))

这实际上很好并且符合我的要求here in this demo

但是:D(这是黄油)

我希望通过使其更具可读性和“紧凑”来优化正则表达式本身。我搜索了如何做到这一点,我找到了一个叫做反向引用的东西,你可以在其中命名你的捕获组,然后再引用它们:

(\(\s*(?P<Val>[a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|\*|\/|\+|\-|==|!=|>|>=|<|<=)\s*(\g{Val})\s*\))

我在那里命名了捕获表达式Val左侧的组,后来我将其引用为(\g{Val}),现在问题就是这个表达式,你可以仅看here表达式左侧与右侧完全相同的情况!例如(a==a)(1==1),与(a==b)

等表达式不匹配

现在的问题是:有没有办法引用模式而不是匹配的值?!

2 个答案:

答案 0 :(得分:3)

请注意,\g{N}相当于\1,即反向引用,它匹配相同的,而不是模式,相应的捕获组匹配。此语法稍微灵活一些,因为您可以在数字前使用-来定义 relative 到当前组的捕获组(即\g{-2},{{ 1}}将匹配(\p{L})(\d)\g{-2})。

PCRE引擎允许subroutine calls递归子模式。要重复第1组的模式,请使用a1a(?1)来递归命名组(?&Val)的模式。

此外,您可以使用字符类来匹配单个字符,并考虑使用Val量词来使正则表达式的部分可选:

?

请参阅regex demo

请注意(\(\s*(?P<Val>[a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|[*\/+-]|[=!><]=|[><])\s*((?&Val))\s*\)) \'.*\'匹配过多,请考虑替换为\[.*\]\'[^\']*\'

答案 1 :(得分:1)

您使用此正则表达式的语言/应用程序是什么? 如果您有选项,则可以将不同的部分指定为命名变量,然后通过组合它们来构建最终的正则表达式。

val = "([a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])"
op = "(ni|in|\*|\/|\+|\-|==|!=|>|>=|<|<=)"
exp = "(\(" .. val .. "\s*" .. op .. "\s*" .. val .. "\))"