Я даже не решаюсь даже опубликовать свой ответ.Вы действительно должны обновить.Версия 8.2 достигает конца жизни прямо сейчас.Перейдите по ссылке @a_horse_with_no_name.
Однако проблема привлекла мое внимание.Следующая демонстрация должна работать с PostgreSQL 8.2 :
SELECT -- content,
rtrim(
regexp_replace(
regexp_replace(
replace(
substring(content
,E'(XXX\\d+|XXX\\d+.*XXX\\d+)') -- kill leading / trailing noise
,',',' ') -- remove all ","
,E'(XXX\\d+)', E'\\1,', 'g') -- terminate X-strings with ","
-- now we can use non-greedy terminated with ","
,E'(XXX\\d+?,)*?.*?(XXX\\d+?,)', E'\\1\\2', 'g')
,',') AS result
FROM (VALUES
('no match')
,('XXX010101')
,('XXX010102 beginn')
,('end XXX010103')
,('middle XXX010104 match')
,('match middle XXX010105 and end XXX010106')
,('XXX010107, match beginn XXX010108 & middle')
,('XXX010109 begin and end XXX010110')
,('XXX01011 begin XXX010112 middle and end XXX010113')
,('XXX01014 begin XXX010115 close matches XX010113 XXXy010113 23624 ,XXX010116')
,('f XXX01017 B XXX010118 457XXX010119 XXXy XXX010120 overkill XXX010121end')
) data(content)
Результат:
result
--------------------------------------------------
-- first line is NULL
XXX010101
XXX010102
XXX010103
XXX010104
XXX010105,XXX010106
XXX010107,XXX010108
XXX010109,XXX010110
XXX01011,XXX010112,XXX010113
XXX01014,XXX010115,XXX010116
XXX01017,XXX010118,XXX010119,XXX010120,XXX010121
Некоторое объяснение:
- нет
regex_matches()
в версии 8.2 в качестве OP уже указано - , но есть
regexp_replace()
, который может использовать флаг g
(заменить g
глобально) - мы не можем смешивать жадные и не жадные квантификаторыв том же регулярном выражении
- , поэтому я заканчиваю нужные строки с помощью
,
, после удаления всех других вхождений ,
Может быть любой символ, не являющийся частью нужных строк, но ,
может служить в качествев результате разделитель. - сначала обрежьте начальные и конечные помехи
- , а затем глобально замените все, что находится между нужными строками.
- , чтобы эта работа использовала
(XXX\\d+?,)*?
для захвата любого числаведущих вхождений искомой строки. final rtrim()
удаляет трейлинг ,
В PsotgreSQL 8.3+ вы можете использовать regexp_split_to_table()
для разделенияхотел строки в один ряд.В 8.2 вы должны придумать что-то свое.Я бы написал функцию plgpsql ...
Это интенсивно использует возможности регулярных выражений POSIX PostgreSQL (ссылка на версию 8.2!)