我有一个正则表达式^(?!.*?([aceg]).*?\1)(?!.*?([i])(?:.*?\2){2})[acegi]+$,它的工作方式是expected(例如在Ruby中),但在PostgreSQL中没有,因为“无效的反向引用号”。
如何解决它并保持给定的功能?
SQL命令的一部分:WHERE (name ~ '^(?!.*?([aceg]).*?\1)(?!.*?([i])(?:.*?\2){2})[acegi]+$')
注意:我试图像\\那样转义反斜杠,但没有任何错误,但PG返回的是无效的匹配项(如“aaa”)。

最佳答案

Postgresql的问题是,首先,它不支持在其lookahead断言中包含捕获组。也就是说,一个lookahead中的所有捕获组都将被视为非捕获组((?: ... )),emphasis mine:
前向约束不能包含后向引用(请参见Section 9.7.3.3),其中的所有括号都被视为未捕获。[1]
因此,即使PostgreSQL确实支持在lookahead中使用backreference,但由于上述限制,它仍然无法按预期工作(如果没有捕获组,则不能使用backreference)。
一个可能的解决方法(对于复杂的需求来说很长,不幸的是)是计算每个字符的数量:

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;

[从this answer获取并修改的条件;最后一行是确保字符串中只有这些字符]

关于regex - PostgreSQL:无效的正则表达式:无效的反向引用号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22751376/

10-12 22:02