O problema com o Postgresql é que, primeiro, ele não suporta ter grupos de captura dentro de suas asserções lookahead. Dito isso, todos os grupos de captura dentro de um lookahead serão tratados como grupos sem captura (
(?: ... )
), destaque meu:Portanto, mesmo se o PostgreSQL suportasse ter referências anteriores dentro de um lookahead, ele ainda não funcionaria conforme o esperado devido à restrição acima (sem um grupo de captura, você não pode ter uma referência anterior).
Uma possível solução alternativa (infelizmente será demorada para requisitos complexos) seria contar o número de cada caractere:
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;
[condição obtida e modificada esta resposta ; a última linha é para garantir que haja apenas esses caracteres na string]