我有一个正则表达式,用于匹配表格的表达式 (val1 operator val2)
(val1 operator val2)
这个正则表达式看起来像:
(\(\s*([a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|\*|\/|\+|\-|==|!=|>|>=|<|<=)\s*([a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*\))
正如您在本演示中看到的那样,这实际上很好,并且与我想要的匹配
但是:D(黄油来了)
我想通过使其更易读和“紧凑”来优化正则表达式本身。我搜索了如何执行此操作,然后找到了一种称为反向引用的名称,您可以在其中命名捕获组,然后像下面这样引用它们:
(\(\s*(?P<Val>[a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|\*|\/|\+|\-|==|!=|>|>=|<|<=)\s*(\g{Val})\s*\))
我在其中命名了捕获表达式左侧的组,Val后来我将其引用为(\g{Val}),现在的 问题 是,仅在表达式左侧与右侧完全相同的情况下,您才能在此处看到此表达式!例如(a==a)或(1==1),并且与(a==b)!之类的表达式不匹配。
Val
(\g{Val})
(a==a)
(1==1)
(a==b)
现在的问题是:有没有办法引用模式而不是匹配的值?
请注意,这\g{N}等效于\1,即, 反向引用 与相应的捕获组匹配的相同 值 (而不是模式)匹配。不过,这种语法稍微灵活一些,因为您可以通过在数字之前使用来定义 相 对于当前组的捕获组-(即\g{-2},(\p{L})(\d)\g{-2}将匹配a1a)。
\g{N}
\1
-
\g{-2}
(\p{L})(\d)\g{-2}
a1a
PCRE引擎允许 子例程调用 来递归子模式。要重复Group 1的模式,请使用(?1)和(?&Val)递归已命名group的模式Val。
(?1)
(?&Val)
另外,您可以使用字符类来匹配单个字符,并考虑使用?量词使正则表达式的某些部分可选:
?
(\(\s*(?P<Val>[a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|[*\/+-]|[=!><]=|[><])\s*((?&Val))\s*\))
见正则表达式演示
请注意,\'.*\'和\[.*\]可能匹配太多,请考虑用\'[^\']*\'和替换\[[^][]*\]。
\'.*\'
\[.*\]
\'[^\']*\'
\[[^][]*\]