Соответствие регулярного выражения в PostgreSQL различается в зависимости от версии - PullRequest
0 голосов
/ 10 февраля 2012

У меня есть приложение, над которым я работаю, и сегодня вечером обнаружилось тревожное различие - и я подумал, что документирую его здесь и посмотрим, сможет ли кто-нибудь его воспроизвести и / или объяснить. Запрос составлен, но демонстрирует проблему:

select 
    '123' ~ '^\d+$' as result_1, 
    '123' ~ '^[0-9]+$' as result_2

У меня PostgreSQL v9.1, работающий в Windows 7, и когда я запускаю этот запрос, я получаю:

Т, Т

Однако, когда я запускаю запрос на PostgreSQL v9.0 на Ubuntu 10.04, я получаю:

F, T

Итак, похоже, что PostgreSQL изменил между v9.0 и v9.1 при обработке «\ d» или что-то связано с различиями между библиотеками, установленными между Windows и Ubuntu.

В любом случае, я думаю, что люди должны знать, что ваши ограничения проверки и т. Д. Могут не вести себя одинаково между ними (моя уверена, что нет).

Примечание: к сожалению, у меня нет простого доступа к Windows 7, работающему под управлением 9.0, или я бы тоже там протестировал.

Может кто-нибудь объяснить это? Если это хорошо известно, пожалуйста, прости меня. Я не видел ответа, когда гуглил по нему. Очевидно, что безопаснее всего использовать [0-9], потому что он работает в обоих местах. Но, опять же, я хотел бы знать, почему это происходит.

1 Ответ

2 голосов
/ 10 февраля 2012

У вас проблема с выходом.Из руководства fine 9.1 по цитированию строк :

Если параметр конфигурации standard_conforming_strings выключен, PostgreSQL распознает экранирование с обратной косой чертой как в обычной, так и в константе escape-строки.Однако, начиная с PostgreSQL 9.1, по умолчанию включено, что означает, что экранирование с обратной косой чертой распознается только в константах escape-строки.

Так что 9.1 видит '\d' так же, как C делает так, что выглядит просто1011 *.В 9.1 вы хотели бы избежать обратной косой черты и использовать E'' нотацию escape-строки, чтобы пройти standard_conforming_strings:

select 
    '123' ~ E'^\\d+$' as result_1, 
    '123' ~ '^[0-9]+$' as result_2

Или вы можете попробовать долларовое цитирование :

select 
    '123' ~ $re$^\d+$$re$ as result_1, 
    '123' ~ '^[0-9]+$' as result_2

но это довольно уродливо и трудно читать с помощью регулярного выражения (особенно регулярного выражения, использующего $ для привязки конца).

Другой вариант - использовать Класс символов POSIX вместо \d:

select 
    '123' ~ '^[[:digit:]]+$' as result_1, 
    '123' ~ '^[0-9]+$' as result_2

Вы также должны были видеть предупреждения о '\d' в более ранних версиях, проверьте в своих журналах такие вещи:

WARNING:  nonstandard use of escape in a string literal
LINE 1: select '\d';
               ^
HINT:  Use the escape string syntax for escapes, e.g., E'\r\n'.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...