2017-01-17 3 views
0

У меня есть текст в колонке, что-то вродеOracle REGEXP_REPLACE и сохранить его часть

Hello World %UC#abc#UC%. How are you %UC#def#UC%. Have a nice day %UC#ghi#UC%. 

Я хочу использовать REGEXP_REPLACE (или любой) функции для замены %UC#<value>#UC% с UNISTR(<value>). Из приведенного выше примера, результат должен быть

Hello World (UNISTR of abc). How are you (UNISTR of def). Have a nice day (UNISTR of ghi). 

В основном он должен содрать %UC# и замените значение в нем с UNISTR значения.

Есть ли способ, которым я могу это достичь?

ответ

0

Это может быть путь в 11g и на:

with test(s) as (select 'Hello World %UC#abc#UC%. How are you %UC#def#UC%. Have a nice day %UC#ghi#UC%.' || '%UC##UC%' from dual) 
select listagg (str) within group (order by lev) 
from (
     select regexp_substr(s, '(^|#UC%)(.*?)(%UC#)', 1, level, '', 2) || 
       UPPER(regexp_substr(s, '(%UC#)(.*?)(#UC%)', 1, level, '', 2)) as str, 
       level as lev 
     from test 
     connect by instr(s, '%UC#', 1, level) > 0 
    ) 

, который дает (я использовал UPPER вместо UNISTR, чтобы сделать результат ясно):

Hello World ABC. How are you DEF. Have a nice day GHI. 

Идея заключается в том, чтобы использовать широко используемая техника с разделенной струной, учитывая детали, обернутые '%UC#...#UC%' в качестве разделителя; обратите внимание, что я добавил небольшую строку ('%UC##UC%') во входную строку для обработки последней части входной строки, заставляя запрос считать, что строка обрабатывается по окончании и (пустой) '%UC#...#UC%'.

В Oracle 10g мы не можем использовать listagg так, как я это сделал, следовательно, решение немного сложнее.

Здесь я не использую никаких регулярных выражений вообще и вычисляю агрегацию с помощью SYS_CONNECT_BY_PATH; чтобы сделать это, мне нужно, чтобы определить строку, которая никогда не будет отображаться в вашем входном тексте, скажем '@@':.

with test as (select 'Hello World %UC#abc#UC%. How are you %UC#def#UC%. Have a nice day %UC#ghi#UC%.' || '%UC##UC%' as s from dual) 

с помощью теста, как (выберите «Hello World% UC# ABC# UC% Как вы% UC# # Защита UC%. хороший день% UC# ГХИ # UC%. || '% UC## UC%', как с двойного с)

select replace (sys_connect_by_path (
           substr(s, case when level = 1 then 1 else instr(s,'#UC%', 1, level-1) +4 end, instr(s, '%UC#', 1, level) -case when level = 1 then 1 else instr(s,'#UC%', 1, level-1) +4 end ) || 
           UPPER(substr(s, instr(s, '%UC#', 1, level) + 4, instr(s,'#UC%', 1, level) - (instr(s, '%UC#', 1, level) + 4))) 
          , '@@' 
          ), 
       '@@') str     
from test 
where connect_by_isleaf = 1 
connect by instr(s, '%UC#', 1, level) > 0 
+0

Я управлял выше запросом и в результате ошибки , 'Ошибка в командной строке: 1 Столбец: 10 Отчет об ошибке - Ошибка SQL: ORA-32033: неподдерживаемый столбец aliasing' – Maz

+0

Только что отредактирован, чтобы показать решение, которое должно работать в 10g – Aleksej

+0

Второй запрос говорит, что' from' отсутствует. Я добавил 'from' dual в конце запроса, и теперь он говорит' ORA-00904: «S»: недопустимый идентификатор' – Maz

Смежные вопросы