regexp со "*" на Linux/Windows

hattifattener
Дата: 12.01.2015 07:01:23
Уважаемые знатоки,

При переносе процедуры между платформами наступил на неприятные грабли:

Разбор строки на однородные подстроки осуществлялся выражением
select regexp_matches('xaabbbccccddddd',E'((.)\\2*)','g');


На Linux/BSD отлично работает, на Windows ломается из-за неверной интерпретации звезды.

Проблему обошел через
E'((.)(\\2+)?)'

но осадок остался.

Подскажите пожалуйста, с чем может быть связан такой эффект.

Версия 9.0.18.
этта
Дата: 12.01.2015 08:18:54
hattifattener,
ща на винде постгреса нет. [недавно переставлял]. но таких багов не помню

навскидку убери префикс E и (сл-но) сними дабл \\ в регекспе [ '((.)\2*)' ]. ничего не поменяется, но вдруг(если да -- то и звизду экранируй с E).

я пр-льно понимаю, что * у вас квантификатор ?
этта
Дата: 12.01.2015 10:22:26
hattifattener,

select regexp_matches('xaabbbccccddddd',E'((.)\\2*)','g');
"{x,x}"
"{aa,a}"
"{bbb,b}"
"{cccc,c}"
"{ddddd,d}"
SELECT version();
"PostgreSQL 9.2.8 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52), 64-bit"


винда:
select regexp_matches('xaabbbccccddddd',E'((.)\\2*)','g');
"{x,x}"
"{aa,a}"
"{bbb,b}"
"{cccc,c}"
"{ddddd,d}"
SELECT version();
"PostgreSQL 9.3.0, compiled by Visual C++ build 1600, 32-bit"

т.е. неясно, что у вас не фурыкает

вариант -- парсер не может понять [платформенная разница в ём] что и в каком порядке квантифицировать и делает \(2*) вместо (\2)*.
попробуйте явно выделить:
select regexp_matches('xaabbbccccddddd','(.)((\1)*)','g');
"{x,"",NULL}"
"{a,a,a}"
"{b,bb,b}"
"{c,ccc,c}"
"{d,dddd,d}"

ну и вариант с экранировкой звизды приведите
hattifattener
Дата: 12.01.2015 12:47:22
этта,


DB=# select regexp_matches('xaabbbccccddddd',E'((.)\\2*)','g');
regexp_matches
---------------------
{xaabbbccccddddd,x}
(1 row)

DB=# select version();
version
-------------------------------------------------------------
PostgreSQL 9.0.3, compiled by Visual C++ build 1500, 32-bit
(1 row)

Для 9.3 работает. Наступалось только на 9.0.

В known bugs ничего похожего. Почему и спрашиваю - может кто в курсе.
hattifattener
Дата: 12.01.2015 12:55:14
этта,

Вариант с '(.)((\1)*)' разбирает строку на символы, а E'(.)((\\1)*)' ломается на односимвольных подстроках и на винде и на линуксе.

Экранировка звезды приводит к тому, что квантификатора кагбе вообще нет, а есть символ звезда - и ведет себя соответсвенно.
этта
Дата: 12.01.2015 16:24:05
hattifattener
этта,
<>
Экранировка звезды приводит к тому, что квантификатора кагбе вообще нет, а есть символ звезда - и ведет себя соответсвенно.


select regexp_matches('xaabbbccccddddd',E'((.)\\2\*)','g');
"{x,x}"
"{aa,a}"
"{bbb,b}"
"{cccc,c}"
"{ddddd,d}"
SELECT version();
"PostgreSQL 9.2.8 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52), 64-bit"
--- вынь : -----------------------
select regexp_matches('xaabbbccccddddd',E'((.)\\2\*)','g');
"{x,x}"
"{aa,a}"
"{bbb,b}"
"{cccc,c}"
"{ddddd,d}"
SELECT version();
"PostgreSQL 9.3.0, compiled by Visual C++ build 1600, 32-bit"


похоже -- какой то баг парсера регекспов 9.0. т.е. экранировка "происходит" (если происходит) после разбора регекспа.
этта
Дата: 12.01.2015 16:31:36
покажите на 9.0 результат в винде и в постгресе

SELECT E'((.)\\2\*)';
--
"((.)\2*)"
hattifattener
Дата: 12.01.2015 19:52:03
--- linux ---

select E'((.)\\2\*)';
---
"((.)\2*)"

select regexp_matches('xaabbbccccddddd',E'((.)\\2\*)','g');
---
 {x,x}
 {aa,a}
 {bbb,b}
 {cccc,c}
 {ddddd,d}


--- вынь ---

select E'((.)\\2\*)';
---
"((.)\2*)"

select regexp_matches('xaabbbccccddddd',E'((.)\\2\*)','g');
---
"{xaabbbccccddddd,x}"


Верно, это я два слеша поставил, когда выражение начало звезду искать. Так получается первый случай.
Видимо таки unknown bug в парсере.
PgSQLanonymous
Дата: 13.01.2015 01:04:28
-- windows:
select version();
---
"PostgreSQL 9.3.4, compiled by Visual C++ build 1600, 32-bit"

select regexp_matches('xaabbbccccddddd',E'((.)\\2\*)','g');
---
 {x,x}
 {aa,a}
 {bbb,b}
 {cccc,c}
 {ddddd,d}