Как найти сегмент текста в сгустке и обернуть его нужным текстом? - PullRequest
0 голосов
/ 12 мая 2019

У меня есть таблица, в которой хранится текст, и мне нужно найти все места, где найден определенный текст, и добавить текст до и после него. Чтобы быть более точным, мне нужно изменить все места, где SomethingToFindвозникает шаблон, найдите пробел перед ним (или началом строки) и следующий ';'и оберните его текстом.

IE преобразуйте это -

TextAboutSomethingToFind.ExampleA;

в это -

/* Caution
  TextAboutSomethingToFind.ExampleA;
Caution */

У меня есть следующий цикл для поиска всех записей стекст, который я ищу.

for x in (select t.id
                     ,t.clobvalue
              from table_name t
            where REGEXP_like(t.clobvalue, 'SomethingToFind')
            )
loop
  --Some Operations
end loop;

Пример текста в clobvalue:

BlahBlah Blah;  
TextAboutSomethingToFind.ExampleA; 
ExtraText; MoreExtraText;EvenMoreExtraText;   
LastExtraText;  
TextAboutSomethingToFind.ExcibitB; TextAboutSomethingToFind.PatternС;  
EndText;  

Желаемый результат:

 BlahBlah Blah;
/* Caution
TextAboutSomethingToFind.ExampleA; 
Caution */
ExtraText; MoreExtraText; EvenMoreExtraText;  
LastExtraText;  
/* Caution
TextAboutSomethingToFind.ExcibitB; 
Caution */ 
/* Caution
TextAboutSomethingToFind.PatternС;
Caution */
EndText;

Я знаю, что мне как-то нужноиспользуйте regexp_replace, но я понятия не имею, как это сделать правильно.Как я могу это сделать?

1 Ответ

0 голосов
/ 12 мая 2019

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

Также предполагается, что каждая «подстрока» (строка) может быть преобразована в VARCHAR2 (с использованием TO_CHAR).

Пример данных:

SQL> select * from test;

COL
--------------------------------------------------------------------------------
BlahBlah Blah;
TextAboutSomethingToFind.ExampleA;
ExtraText; MoreExtraText;EvenMoreExtraText;
LastExtraText;
TextAboutSomethingToFind.ExcibitB; TextAboutSomethingToFind.Pattern?;
EndText;

Решение, написанное по-моему . Следуйте за комментариями в коде. Если вы не уверены в том, что он делает, запустите его CTE за CTE и посмотрите значения, которые возвращает каждый из этих SELECT s.

SQL> with temp2 as
  2    -- split multi-lines column to rows, separated by CHR(10)
  3    (select level lvl2,
  4            to_char(regexp_substr(col, '[^' || chr(10) ||']+', 1, level, 'm')) col2
  5     from test
  6     connect by level <= regexp_count(col, chr(10)) + 1
  7    ),
  8  temp3 as
  9    -- out of all rows from the previous step, split those - that contain "SomethingToFind"
 10    -- more than once - into their own separate rows
 11    (select lvl2,
 12            level lvl3,
 13            trim(to_char(regexp_substr(col2, '[^;]+', 1, level))) col3
 14     from (select lvl2,
 15                  col2 from temp2
 16           where instr(col2, 'SomethingToFind') > 0
 17             and regexp_count(col2, ';') > 1
 18          )
 19     connect by level <= regexp_count(col2, ';')
 20    ),
 21  almost_there as
 22    -- apply the "Caution" clause to all "SomethingToFinds" from both cases
 23    (select lvl2,
 24            to_number(null) lvl3,
 25            case when instr(col2, 'SomethingToFind') > 0 then
 26                      '/* Caution' ||chr(10) || col2 || chr(10) || 'Caution */'
 27                 else col2
 28            end col
 29     from temp2
 30     where lvl2 not in (select lvl2 from temp3)
 31     union all
 32     select lvl2,
 33            lvl3,
 34            case when instr(col3, 'SomethingToFind') > 0 then
 35                      '/* Caution' ||chr(10) || col3 || chr(10) || 'Caution */'
 36                 else col3
 37            end col
 38     from temp3
 39    )
 40  -- Finally, put them together using LISTAGG, separated by CHR(10)
 41  select listagg(col, chr(10)) within group (order by lvl2, lvl3) result
 42  from almost_there;

RESULT
--------------------------------------------------------------------------------
BlahBlah Blah;
/* Caution
TextAboutSomethingToFind.ExampleA;
Caution */
ExtraText; MoreExtraText;EvenMoreExtraText;
LastExtraText;
/* Caution
TextAboutSomethingToFind.ExcibitB
Caution */
/* Caution
TextAboutSomethingToFind.Pattern?
Caution */
EndText;


SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...