Regexp在不区分大小写模式下截断命名捕获组中的“in”字

时间:2016-08-18 06:05:58

标签: regex pcre

我有正则表达式:

/(t0|t1)\.(?<column>(.*?))\s*(?<opt>(=|>=|<=|<|>|IN|LIKE))\s*(?<search>(.*|$))/i

应该标记化类生成子句的位置,以便将它们提供给外部Web服务。在区分大小写模式下,它可以正常工作,但不是在不区分大小写的模式下。请查看下面的演示。

如果有“in”字,则名称捕获组截断工作,例如

t0.date_finished > 'somedate'

我期待

  

[column =&gt; date_finished]

而不是

  

[column =&gt; date_f]

我缺少什么?

demo

1 个答案:

答案 0 :(得分:2)

您需要在IN群组的LIKEopts周围使用字词边界:

(t0|t1)\.(?<column>.*?)\s*(?<opt>>=|<=|=|<|>|\b(?:IN|LIKE)\b)\s*(?<search>.*)
                                             ^^^^^^^^^^^^^^^    

请参阅regex demo

此外,您不需要在命名捕获组内捕获组,我以建议的模式删除它们。

如果您在非单词序列周围添加\b字边界,则只会在字词字符之前和之前匹配(\b=\b将与=字符串中的word1=word1匹配)

请注意,opt组中的较长选项必须在较短的选项之前。

此外,可以使用字符类优化opt组:

(t0|t1)\.(?<column>.*?)\s*(?<opt>[><]=|[=<>]|\b(?:IN|LIKE)\b)\s*(?<search>.*)
                                 ^^^^^^^^^^^

[><]=|[=<>]匹配>=<=[><]=部分)或(|)a =,{{1} },或<