Удаление текста между HTML-тегами в oracle sql

#sql #oracle

Вопрос:

У нас есть требование удалить весь HTML-текст, присутствующий в коде. Например, для приведенного ниже текста:

 Notes Test with Text between Tags Part 2<div> <a> test</a> Inside Tags </div>
 

Ожидаемый результат составляет:

 Notes Test with Text between Tags Part 2
 

Я попробовал приведенный ниже код, но он удаляет только HTML-теги, а не текст между ними. Пожалуйста, обратите внимание, что HTML-текст может быть чем угодно, например, тегом внутри тега внутри тега.:

 SELECT REGEXP_REPLACE ('Notes Test with Text between Tags Part 2<div> <a> test</a> Inside Tags </div>', '<. ?>') from dual
 

Комментарии:

1. Ваш подход неверен (в целом) , независимо от всего остального. Вы не хотите сопоставлять теги — вы просто ищете символы < , > которые могут появляться во многих других контекстах в ваших строковых значениях, не связанных с HTML-тегами. Если на самом деле они не могут, это дополнительная информация, которой вы не поделились с нами в своем вопросе.

2. Есть ли какой-либо способ удалить весь текст в HTML-тегах, включая HTML-теги в SQL?

3. Обратите внимание, что some text <br> some text <br> another text это также допустимо, но здесь нет вложенных структур.

4. Просто удалите не жадный квантификатор, '<. ?>' чтобы он '<. >' работал, и он начнет работать. В любом случае вы получите гораздо лучшую производительность (для больших данных), используя instr substr подход/.

Ответ №1:

Если HTML-часть всегда будет последней в строке, то вы можете использовать следующий запрос —

 SELECT SUBSTR ('Notes Test with Text between Tags Part 2<div> <a> test</a> Inside Tags </div>'
               ,1
               , INSTR('Notes Test with Text between Tags Part 2<div> <a> test</a> Inside Tags </div>', '<') - 1
              )
from dual
 

Комментарии:

1. html-часть не всегда будет последней частью

Ответ №2:

Если вы хотите удалить подстроку между первым появлением < и последним появлением > (я намеренно не говорю об HTML этом )

чем instr твой друг.

Просто найдите положение подстрок:

первое появление <

    instr(text,'<')-1 first_pos,
 

последнее появление >

    instr(text,'>',-1,1) 1 last_pos 
 

и используйте substr , чтобы удалить ненужную часть. Я добавил в запрос некоторую обработку несоответствий (которые могут появиться в вашей строке, если вы, например, объедините HTML с формулой 2 > 1 — см. Примеры ниже), не стесняйтесь адаптировать их к вашим требованиям

Запрос с образцами данных

 with tab as 
(select 'Notes Test with Text between Tags Part 2<div> <a> test</a> Inside Tags </div>' text from dual union all
 select 'Notes without Text' from dual union all
 select 'Notes < inconsistent' from dual union all
 select 'Notes2 > inconsistent2' from dual),
tab2 as (
select text,
       instr(text,'<')-1 first_pos,
       instr(text,'>',-1,1) 1 last_pos
from tab)
select text, 
       substr(text,1,first_pos) || case when (first_pos = -1 and last_pos = 1) then substr(text,last_pos) end new_txt
from tab2 

TEXT                                                                          NEW_TXT                                                                                                                                                   
----------------------------------------------------------------------------- -------------------------------------------
Notes Test with Text between Tags Part 2<div> <a> test</a> Inside Tags </div> Notes Test with Text between Tags Part 2                                                                                                                  
Notes without Text                                                            Notes without Text                                                                                                                                        
Notes < inconsistent                                                          Notes                                                                                                                                                     
Notes2 > inconsistent2
 

Ответ №3:

Это может сделать вашу работу. Он охватывает еще два случая :

  • Случай, когда html-часть не является последней частью
  • Случай, когда у вас был бы вложенный html (например, вложенный html )
 with t (col) as (
SELECT 'Notes Test with Text between Tags Part 2<div> <a> test </a> Inside Tags </div>' from dual union all
SELECT 'Notes Test with Text between Tags Part 2<div> <a> test </a> Inside Tags </div> html part is not going to be the last part always' from dual union all
SELECT 'Notes Test with Text between Tags Part 2<div> whatever xxx <div> whatever yyy </div> <a> test </a> Inside Tags </div> html part is not going to be the last part always' from dual
)
select 
    col
  , substr(col, 1, left_part_end#) 
      || substr(col
          , instr(col, '</'||match_balise||'>'
          , -1
          , 1)   length(match_balise)   3 
                /* why 3 ? ==> 3 = length('</>') */
        ) html_removed_col
from (
  select col
      , regexp_instr(col, '^(.*?)(<(. ?)>). ?(</3>)(.*?)

db<>скрипка



, 1, 1, 0, '', 2 ) - 1 left_part_end#
, substr (col
, regexp_instr(col, '^(.*?)(<(. ?)>). ?(</3>)(.*?)db<>скрипка

, 1, 1, 0, '', 3 )
, regexp_instr(col, '^(.*?)(<(. ?)>). ?(</3>)(.*?)db<>скрипка

, 1, 1, 1, '', 3 )
- regexp_instr(col, '^(.*?)(<(. ?)>). ?(</3>)(.*?)db<>скрипка

, 1, 1, 0, '', 2 ) - 1
) match_balise
from t
)
;
db<>скрипка