Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Выбор построки, ограниченной маркерами  [new]
Kr_Yury
Member

Откуда: Киев, Украина
Сообщений: 244
Требуется из строки вида "что-то НАЧАЛО что-то КОНЕЦ хвост" выделить подстроку между "НАЧАЛО" и "КОНЕЦ"
Помогите составить шаблон. И посоветуйте ресурс (книгу, сайт), где хорошо объясняются регулярные выражения, и с большим количеством примеров. Пытался разобраться с регуляркой по докам Oracle и Postrgesql, но безрезультатно
6 ноя 20, 13:53    [22227513]     Ответить | Цитировать Сообщить модератору
 Re: Выбор построки, ограниченной маркерами  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
SELECT UNNEST(regexp_matches(  -- i = без учёта регистра
'голова1 НАЧАЛО что-то1 КОНЕЦ хвост1 НАЧАЛО что-то2 КОНЕЦ хвост2', '(?<=\s|^)НАЧАЛО\s+([^\s]+)\s+КОНЕЦ(?=\s|$)', 'ig'));

что-то1
что-то2

Перед вставкой в регулярное выражение фрагментов "НАЧАЛО" и "КОНЕЦ" их нужно экранировать.
6 ноя 20, 14:44    [22227545]     Ответить | Цитировать Сообщить модератору
 Re: Выбор построки, ограниченной маркерами  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
Если "что-то" может содержать пробелы, можно сделать так:
SELECT UNNEST(regexp_matches(
'голова1 НАЧАЛО что-то1 КОНЕЦ хвост1 НАЧАЛО что то2 КОНЕЦ хвост2', '(?<=\s|^)НАЧАЛО\s+(.+?)\s+КОНЕЦ(?=\s|$)', 'ig'));

что-то1
что то2
6 ноя 20, 15:13    [22227560]     Ответить | Цитировать Сообщить модератору
 Re: Выбор построки, ограниченной маркерами  [new]
Kr_Yury
Member

Откуда: Киев, Украина
Сообщений: 244
Cyrax_02, этот вариант не работает, а пробелы действительно могут быть. Результат
"что-то1 КОНЕЦ хвост1 НАЧАЛО что то2"
Cyrax_02, спасибо. Мне этого пока хватит
6 ноя 20, 16:31    [22227618]     Ответить | Цитировать Сообщить модератору
 Re: Выбор построки, ограниченной маркерами  [new]
Cyrax_02
Member

Откуда:
Сообщений: 1396
Kr_Yury
Cyrax_02
Если "что-то" может содержать пробелы, можно сделать так:
SELECT UNNEST(regexp_matches(
'голова1 НАЧАЛО что-то1 КОНЕЦ хвост1 НАЧАЛО что то2 КОНЕЦ хвост2', '(?<=\s|^)НАЧАЛО\s+(.+?)\s+КОНЕЦ(?=\s|$)', 'ig'));

что-то1 КОНЕЦ хвост1 НАЧАЛО что то2
Cyrax_02, этот вариант не работает, а пробелы действительно могут быть. Результат
"что-то1 КОНЕЦ хвост1 НАЧАЛО что то2"
Регулярное выражение корректное. Проверил в PHP/pcre - работает корректно (находит два фрагмента "что-то1" и "что то2").
Почему не работает в PostgreSQL/posix - неизвестно. Либо странный артефакт posix, либо тупой баг реализации в PostgreSQL.
Что происходит: жадный квантификатор + перед нежадным +? делает последний жадным (блокирует действие оператора ?).

В качестве решения можно заменить конструкцию \s+ конструкцией \s+?(?!\s), дающую тот же результат, но при этом артефакт не наблюдается:
SELECT UNNEST(regexp_matches(
'голова1 НАЧАЛО   что-то1   КОНЕЦ хвост1 НАЧАЛО   что то2   КОНЕЦ хвост2',
'(?<=\s|^)НАЧАЛО\s+?(?!\s)(.+?)\s+КОНЕЦ(?=\s|$)', 'ig'));  -- i = без учёта регистра

что-то1
что то2
P.S. Судя по молчанию, регулярные выражения в PostgreSQL народ не любит...

Сообщение было отредактировано: 8 ноя 20, 07:21
8 ноя 20, 07:23    [22228217]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить