Postgresql:无效的正则表达式:无效的反向引用号

时间:2014-03-30 23:40:33

标签: regex postgresql

我有这个正则表达式^(?!.*?([aceg]).*?\1)(?!.*?([i])(?:.*?\2){2})[acegi]+$,它作为expected(例如在Ruby中),但由于“无效的反引用号”而不在PostgreSQL中。

如何解决它并保持给定的功能?

SQL命令的一部分:WHERE (name ~ '^(?!.*?([aceg]).*?\1)(?!.*?([i])(?:.*?\2){2})[acegi]+$')

注意:我尝试使用\\转义反斜杠而没有任何错误,但是PG返回了无效匹配(例如“aaa”)。

2 个答案:

答案 0 :(得分:3)

Postgresql的问题在于,首先,它不支持在其前瞻断言中拥有捕获组。也就是说,预测中的所有捕获组都将被视为非捕获组((?: ... )),强调我的:

  

前瞻约束不能包含后向引用(请参阅Section 9.7.3.3),其中的所有括号都被视为非捕获。 {{3} }

因此,即使PostgreSQL确实支持在前瞻中进行反向引用,由于上述约束(没有捕获组,您也无法进行反向引用),它仍然无法按预期工作。


可能的解决方法(不幸的是,对于复杂的要求将会很长)将计算每个字符的数量:

WHERE
    LENGTH(REGEXP_REPLACE(name, '[^a]+', '', 'g')) < 2 AND
    LENGTH(REGEXP_REPLACE(name, '[^c]+', '', 'g')) < 2 AND
    LENGTH(REGEXP_REPLACE(name, '[^e]+', '', 'g')) < 2 AND
    LENGTH(REGEXP_REPLACE(name, '[^g]+', '', 'g')) < 2 AND
    LENGTH(REGEXP_REPLACE(name, '[^i]+', '', 'g')) < 3 AND
    LENGTH(REGEXP_REPLACE(name, '[acegi]+', '', 'g')) = 0;

[从[1]采取和修改的条件;最后一行是为了确保字符串中只有那些字符

答案 1 :(得分:1)