我有一个正则表达式,用于匹配表单(val1 operator val2)的表达式。
这个regex看起来是:
(\(\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}),然后将其引用为(\g{Val}),现在的问题是,您可以看到的这个表达式只有在表达式的左侧与右侧完全相同的情况下才能看到这里!例如(a==a)或(1==1),并且不匹配表达式,如(a==b)!
现在的问题是:是否有一种方法来引用模式而不是匹配的值?!
发布于 2016-08-17 09:18:55
请注意,\g{N}等效于\1,即匹配对应捕获组匹配的相同值(而不是模式)的反向引用。但是,这个语法稍微灵活一些,因为您可以在数字之前使用- (即\g{-2},(\p{L})(\d)\g{-2}将匹配a1a)来定义相对于当前组的捕获组。
PCRE引擎允许子程序调用恢复子模式。要重复组1的模式,请使用(?1)和(?&Val)来恢复命名组Val的模式。
此外,您可以使用字符类来匹配单个字符,并考虑使用?量词使regex的部分内容成为可选的:
(\(\s*(?P<Val>[a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])\s*(ni|in|[*\/+-]|[=!><]=|[><])\s*((?&Val))\s*\))请注意,\'.*\'和\[.*\]可能匹配得太多,请考虑使用\'[^\']*\'和\[[^][]*\]替换。
发布于 2016-08-17 09:22:04
您在哪种语言/应用程序中使用这个正则表达式?如果您有此选项,您可以将不同的部分指定为命名变量,然后通过组合它们构建最终的正则表达式。
val = "([a-zA-Z]+[0-9]*|[0-9]+|\'.*\'|\[.*\])"
op = "(ni|in|\*|\/|\+|\-|==|!=|>|>=|<|<=)"
exp = "(\(" .. val .. "\s*" .. op .. "\s*" .. val .. "\))"https://stackoverflow.com/questions/38992457
复制相似问题