Você não precisa escapar
- dentro das classes de caracteres quando você o coloca na primeira ou na última posição, porque não pode ser mal interpretado como intervalo dessa maneira:[\- ] -> [- ] [\d\- ] -> [\d -] A maneira como você tem o limite superior
10 no final é inútil.Adicione
$ no final para não permitir caracteres à direita.Ou
\D para não permitir dígitos à direita (mas requer um não dígito).Ou
($|\D) para terminar a string lá ou ter um seguimento sem dígito. Coloque junto:
SELECT '+79637434199' ~ '^(8|\+7)[ -]?(\(?\d{3}\)?[ -]?)[\d -]{7,10}($|\D)'
Caso contrário, sua expressão está bem e funciona para mim no PostgreSQL 9.1.4. Não deve fazer qualquer diferença se você usá-lo em um
WHERE cláusula ou em um SELECT list - a menos que você esteja encontrando um bug com alguma versão antiga (como @kgrittn sugerido nos comentários). Se eu preceder o literal de string com
E , posso provocar a mensagem de erro que você recebe. Isso não pode explique seu problema, porque você afirmou que a expressão funciona bem como SELECT item. Mas, como Sherlock Holmes é citado, "quando você exclui o impossível, o que resta, por mais improvável que seja, deve ser a verdade".
Talvez você tenha executado um teste com
standard_conforming_strings = on
e o outro com standard_conforming_strings = off - esta era a interpretação padrão de literais de string em versões mais antigas antes de 9.1. Talvez com dois clientes diferentes (que têm uma configuração diferente quanto a isso). Leia mais no capítulo Constantes de string com escapes estilo C no manual.