Удалить все элементы внутри кавычек

Рейтинг: 0Ответов: 1Опубликовано: 14.02.2023

Есть текстовое поле, включающее в себя HTML-теги, наподобие:

<p style="margin-top: 0px;" dir="lt"> ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ ТЕКСТ <div id="mail-app-auto"> <p dir="lt">-- Отправлено из Mail.ru для Android </BODY></HTML>

Нужно вытащить отсюда только текст, удалив при этом все теги. Не совсем понятно, как сделать это именно в MS SQL, при отсутствии REGEXP

Ответы

▲ 2

Пожалуйста, попробуйте следующее решение.

Оно использует токенизацию через XML и XQuery.

Промежуточный XML будет выглядеть следующим образом:

<root>
  <r />
  <r>~p style="margin-top: 0px;" dir="lt"</r>
  <r> ТЕКСТ ТЕКСТ </r>
  <r>~div id="mail-app-auto"</r>
  <r>  </r>
  <r>~p dir="lt"</r>
  <r>-- Отправлено из Mail.ru для Android </r>
  <r>~/BODY</r>
  <r />
  <r>~/HTML</r>
  <r />
</root>

Итак, нам нужно отфильтровать пустые теги <r />, а также теги, имеющие первое значение как намеренно вставленный символ тильды. Это делается с помощью выражения XQuery FLWOR с использованием метода .query().

SQL

-- DDL и образец вставки данных, начало
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, tokens NVARCHAR(MAX));
INSERT @tbl (tokens) VALUES
(N'<p style="margin-top: 0px;" dir="lt"> ТЕКСТ ТЕКСТ <div id="mail-app-auto">  <p dir="lt">-- Отправлено из Mail.ru для Android </BODY></HTML>');
-- DDL и образец вставки данных, конец

DECLARE @bogus CHAR(1) = '~';

SELECT t.* --,c
    , result = c.query('
        for $x in /root/r[text()]
            [not(substring(text()[1],1,1)=sql:variable("@bogus"))]
            /text()
        return $x
    ').value('.', 'NVARCHAR(MAX)')
FROM @tbl AS t
CROSS APPLY (SELECT REPLACE(tokens, '<', '>' + @bogus)) AS t1(s)
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
      REPLACE(s, '>', ']]></r><r><![CDATA[') + 
      ']]></r></root>' AS XML)) AS t2(c)

Результат

ID result
1 ТЕКСТ ТЕКСТ -- Отправлено из Mail.ru для Android