Der beste Weg, um HTML-Tags von einer Zeichenfolge in SQL Server zu entfernen?


112

Ich habe Daten in SQL Server 2005, die HTML-Tags enthalten, und ich möchte all das entfernen und nur den Text zwischen den Tags belassen. Ideal auch Dinge wie Ersetzen &lt;mit <etc.

Gibt es eine einfache Möglichkeit, dies zu tun, oder hat jemand bereits einen Beispiel-T-SQL-Code?

Ich habe nicht die Möglichkeit, erweiterte gespeicherte Prozesse und dergleichen hinzuzufügen, daher würde ich einen reinen t-sql-Ansatz bevorzugen (vorzugsweise einen abwärtskompatiblen mit sql 2000).

Ich möchte die Daten nur mit entferntem HTML abrufen, nicht aktualisieren, daher sollte sie idealerweise als benutzerdefinierte Funktion geschrieben werden, um eine einfache Wiederverwendung zu ermöglichen.

So konvertieren Sie zum Beispiel Folgendes:

<B>Some useful text</B>&nbsp;
<A onclick="return openInfo(this)"
   href="http://there.com/3ce984e88d0531bac5349"
   target=globalhelp>
   <IMG title="Source Description" height=15 alt="Source Description" 
        src="/ri/new_info.gif" width=15 align=top border=0>
</A>&gt;&nbsp;<b>more text</b></TD></TR>

dazu:

Some useful text > more text

Antworten:


161

Es gibt eine UDF, die das hier beschriebene tut:

Benutzerdefinierte Funktion zum Entfernen von HTML

CREATE FUNCTION [dbo].[udf_StripHTML] (@HTMLText VARCHAR(MAX))
RETURNS VARCHAR(MAX) AS
BEGIN
    DECLARE @Start INT
    DECLARE @End INT
    DECLARE @Length INT
    SET @Start = CHARINDEX('<',@HTMLText)
    SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
    SET @Length = (@End - @Start) + 1
    WHILE @Start > 0 AND @End > 0 AND @Length > 0
    BEGIN
        SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')
        SET @Start = CHARINDEX('<',@HTMLText)
        SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
        SET @Length = (@End - @Start) + 1
    END
    RETURN LTRIM(RTRIM(@HTMLText))
END
GO

Bearbeiten: Beachten Sie, dass dies für SQL Server 2005 gilt. Wenn Sie jedoch das Schlüsselwort MAX in 4000 ändern, funktioniert es auch in SQL Server 2000.


9
Vielen Dank. Kommentare dort verlinken auf eine verbesserte Version: lazycoders.blogspot.com/2007/06/…, die sich mit mehr HTML-Entitäten befasst.
Rory

4
Beachten Sie, dass dies als stringintensive UDF in SQL Server 2005 oder höher ein perfekter Kandidat für die Implementierung einer CLR-UDF-Funktion für eine massive Leistungssteigerung ist. Weitere Informationen dazu hier: stackoverflow.com/questions/34509/…
RedFilter

10
Beachten Sie, dass der Lazycoder-Beitrag zwei Tippfehler enthält. Entfernen Sie die einfachen Anführungszeichen CHAR(13) + CHAR(10)in zwei der Abschnitte, in denen diese enthalten sind. Subtil genug, dass ich es nicht gefangen habe, bis es die Länge eines kurzen Feldes überschritten hat (interessanterweise und für mich erforderlich, sind alle Ersetzungen kürzer als die ursprüngliche Saite).
Goodeye

1
Was ist mit HTML-codierten Werten? würde sie entschlüsseln brauchen. Vielen Dank.
JDPeckham

2
Ich habe die Lazycoder und den Tippfehler von @goodeye oben verwendet - funktioniert großartig. Um Zeit zu sparen, ist die Lazycoders-Blog-Version hier: lazycoders.blogspot.com/2007/06/…
qxotk

17

Abgeleitet von der Antwort von @Goner Doug, wobei einige Dinge aktualisiert wurden:
- Verwenden von REPLACE, wo möglich
- Konvertierung vordefinierter Entitäten wie &eacute;(ich habe die benötigten ausgewählt :-)
- Konvertierung von Listen-Tags<ul> and <li>

ALTER FUNCTION [dbo].[udf_StripHTML]
--by Patrick Honorez --- www.idevlop.com
--inspired by http://stackoverflow.com/questions/457701/best-way-to-strip-html-tags-from-a-string-in-sql-server/39253602#39253602
(
@HTMLText varchar(MAX)
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @Start  int
DECLARE @End    int
DECLARE @Length int

set @HTMLText = replace(@htmlText, '<br>',CHAR(13) + CHAR(10))
set @HTMLText = replace(@htmlText, '<br/>',CHAR(13) + CHAR(10))
set @HTMLText = replace(@htmlText, '<br />',CHAR(13) + CHAR(10))
set @HTMLText = replace(@htmlText, '<li>','- ')
set @HTMLText = replace(@htmlText, '</li>',CHAR(13) + CHAR(10))

set @HTMLText = replace(@htmlText, '&rsquo;' collate Latin1_General_CS_AS, ''''  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&quot;' collate Latin1_General_CS_AS, '"'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&amp;' collate Latin1_General_CS_AS, '&'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&euro;' collate Latin1_General_CS_AS, '€'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&lt;' collate Latin1_General_CS_AS, '<'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&gt;' collate Latin1_General_CS_AS, '>'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&oelig;' collate Latin1_General_CS_AS, 'oe'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&nbsp;' collate Latin1_General_CS_AS, ' '  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&copy;' collate Latin1_General_CS_AS, '©'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&laquo;' collate Latin1_General_CS_AS, '«'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&reg;' collate Latin1_General_CS_AS, '®'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&plusmn;' collate Latin1_General_CS_AS, '±'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&sup2;' collate Latin1_General_CS_AS, '²'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&sup3;' collate Latin1_General_CS_AS, '³'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&micro;' collate Latin1_General_CS_AS, 'µ'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&middot;' collate Latin1_General_CS_AS, '·'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ordm;' collate Latin1_General_CS_AS, 'º'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&raquo;' collate Latin1_General_CS_AS, '»'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&frac14;' collate Latin1_General_CS_AS, '¼'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&frac12;' collate Latin1_General_CS_AS, '½'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&frac34;' collate Latin1_General_CS_AS, '¾'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Aelig' collate Latin1_General_CS_AS, 'Æ'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Ccedil;' collate Latin1_General_CS_AS, 'Ç'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Egrave;' collate Latin1_General_CS_AS, 'È'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Eacute;' collate Latin1_General_CS_AS, 'É'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Ecirc;' collate Latin1_General_CS_AS, 'Ê'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&Ouml;' collate Latin1_General_CS_AS, 'Ö'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&agrave;' collate Latin1_General_CS_AS, 'à'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&acirc;' collate Latin1_General_CS_AS, 'â'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&auml;' collate Latin1_General_CS_AS, 'ä'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&aelig;' collate Latin1_General_CS_AS, 'æ'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ccedil;' collate Latin1_General_CS_AS, 'ç'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&egrave;' collate Latin1_General_CS_AS, 'è'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&eacute;' collate Latin1_General_CS_AS, 'é'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ecirc;' collate Latin1_General_CS_AS, 'ê'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&euml;' collate Latin1_General_CS_AS, 'ë'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&icirc;' collate Latin1_General_CS_AS, 'î'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ocirc;' collate Latin1_General_CS_AS, 'ô'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ouml;' collate Latin1_General_CS_AS, 'ö'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&divide;' collate Latin1_General_CS_AS, '÷'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&oslash;' collate Latin1_General_CS_AS, 'ø'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ugrave;' collate Latin1_General_CS_AS, 'ù'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&uacute;' collate Latin1_General_CS_AS, 'ú'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&ucirc;' collate Latin1_General_CS_AS, 'û'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&uuml;' collate Latin1_General_CS_AS, 'ü'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&quot;' collate Latin1_General_CS_AS, '"'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&amp;' collate Latin1_General_CS_AS, '&'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&lsaquo;' collate Latin1_General_CS_AS, '<'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&rsaquo;' collate Latin1_General_CS_AS, '>'  collate Latin1_General_CS_AS)


-- Remove anything between <STYLE> tags
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('<', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '')
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('</STYLE>', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1
END

-- Remove anything between <whatever> tags
SET @Start = CHARINDEX('<', @HTMLText)
SET @End = CHARINDEX('>', @HTMLText, CHARINDEX('<', @HTMLText))
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '')
SET @Start = CHARINDEX('<', @HTMLText)
SET @End = CHARINDEX('>', @HTMLText, CHARINDEX('<', @HTMLText))
SET @Length = (@End - @Start) + 1
END

RETURN LTRIM(RTRIM(@HTMLText))

END

4
Ich habe dies verwendet und liebe es, aber ich habe der obersten Gruppe noch einen Ersatz hinzugefügt: </ p> Ich habe zu einem Zeichen 13 + Zeichen 10 gewechselt, auch da das Ende eines Absatz-Tags normalerweise eine neue Zeile anzeigt. Es funktionierte perfekt in meinem speziellen Szenario
DR

1
Diese Antwort hat größtenteils gut funktioniert, aber es wird davon ausgegangen, dass alle Ihre HTML-Tags gültig sind. In meinem Fall gab es beim VARCHAR-Upload ein Kürzungsproblem, durch das einige schließende Tags beseitigt wurden. Ein einfacher PATINDEX RTrim hat es geschafft, alles andere zu entfernen.
matt123788

2
Zusätzlich zu der Änderung, die @DR vorgenommen hat (plus ein paar weitere, die Wagenrückläufe benötigten), habe ich auch die Ersetzungen verschoben, die zu <und >bis zum Ende führen. Ansonsten wurden sie mit den Tags entfernt.
a_hardin

8

Wenn Ihr HTML-Code gut geformt ist, ist dies meiner Meinung nach eine bessere Lösung:

create function dbo.StripHTML( @text varchar(max) ) returns varchar(max) as
begin
    declare @textXML xml
    declare @result varchar(max)
    set @textXML = REPLACE( @text, '&', '' );
    with doc(contents) as
    (
        select chunks.chunk.query('.') from @textXML.nodes('/') as chunks(chunk)
    )
    select @result = contents.value('.', 'varchar(max)') from doc
    return @result
end
go

select dbo.StripHTML('This <i>is</i> an <b>html</b> test')

1
Das hat bei mir funktioniert. +1. Aber könnten Sie bitte Ihren Code erklären, damit Entwickler ihn leichter verstehen? :)
Saeed Neamati

Es sieht so aus, als würde das HTML als XML-Dokument geladen und dann alle Werte daraus ausgewählt. Hinweis: Dieser Code kotzt auf & nbsp;
JDPeckham

2
Setzen Sie einen Hack ein, um HTML-Codes nicht zu bombardieren. Offensichtlich nur ein kurzer Hack für den internen Gebrauch oder was auch immer (genau wie bei akzeptierten UDF).
DudeNumber4

Es muss gut geformt sein, damit es nicht so fehlertolerant ist wie das von RedFilter.
Micah B.

1
HTML ist keine Teilmenge von XML. XHTML ist es, aber HTML ist nicht mehr auf diesem Weg.
David

7

Hier ist eine aktualisierte Version dieser Funktion, die die RedFilter-Antwort (Pinals Original) mit den LazyCoders-Ergänzungen und den Goodeye-Tippfehlerkorrekturen UND meiner eigenen Ergänzung zur Behandlung von Inline- <STYLE>Tags im HTML enthält.

ALTER FUNCTION [dbo].[udf_StripHTML]
(
@HTMLText varchar(MAX)
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @Start  int
DECLARE @End    int
DECLARE @Length int

-- Replace the HTML entity &amp; with the '&' character (this needs to be done first, as
-- '&' might be double encoded as '&amp;amp;')
SET @Start = CHARINDEX('&amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '&')
SET @Start = CHARINDEX('&amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &lt; with the '<' character
SET @Start = CHARINDEX('&lt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '<')
SET @Start = CHARINDEX('&lt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &gt; with the '>' character
SET @Start = CHARINDEX('&gt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '>')
SET @Start = CHARINDEX('&gt;', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &amp; with the '&' character
SET @Start = CHARINDEX('&amp;amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '&')
SET @Start = CHARINDEX('&amp;amp;', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1
END

-- Replace the HTML entity &nbsp; with the ' ' character
SET @Start = CHARINDEX('&nbsp;', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, ' ')
SET @Start = CHARINDEX('&nbsp;', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1
END

-- Replace any <br> tags with a newline
SET @Start = CHARINDEX('<br>', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, CHAR(13) + CHAR(10))
SET @Start = CHARINDEX('<br>', @HTMLText)
SET @End = @Start + 3
SET @Length = (@End - @Start) + 1
END

-- Replace any <br/> tags with a newline
SET @Start = CHARINDEX('<br/>', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, CHAR(13) + CHAR(10))
SET @Start = CHARINDEX('<br/>', @HTMLText)
SET @End = @Start + 4
SET @Length = (@End - @Start) + 1
END

-- Replace any <br /> tags with a newline
SET @Start = CHARINDEX('<br />', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, CHAR(13) + CHAR(10))
SET @Start = CHARINDEX('<br />', @HTMLText)
SET @End = @Start + 5
SET @Length = (@End - @Start) + 1
END

-- Remove anything between <STYLE> tags
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('<', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '')
SET @Start = CHARINDEX('<STYLE', @HTMLText)
SET @End = CHARINDEX('</STYLE>', @HTMLText, CHARINDEX('</STYLE>', @HTMLText)) + 7
SET @Length = (@End - @Start) + 1
END

-- Remove anything between <whatever> tags
SET @Start = CHARINDEX('<', @HTMLText)
SET @End = CHARINDEX('>', @HTMLText, CHARINDEX('<', @HTMLText))
SET @Length = (@End - @Start) + 1

WHILE (@Start > 0 AND @End > 0 AND @Length > 0) BEGIN
SET @HTMLText = STUFF(@HTMLText, @Start, @Length, '')
SET @Start = CHARINDEX('<', @HTMLText)
SET @End = CHARINDEX('>', @HTMLText, CHARINDEX('<', @HTMLText))
SET @Length = (@End - @Start) + 1
END

RETURN LTRIM(RTRIM(@HTMLText))

END

1
Zu meiner Information, aus irgendeinem Grund STUFF()anstelle von REPLACE()(welche wäre kürzer IMO)?
Patrick Honorez

Ich hatte nicht wirklich darüber nachgedacht. Ich habe das Original einfach wie angegeben kopiert / geändert. Ersetzen könnte eine bessere Option sein. Ich frage mich, ob es einen Leistungsvergleich zwischen den beiden zu berücksichtigenden Funktionen gibt ...
Goner Doug

1
@GonerDoug jubelt dem zu, las die akzeptierten Kommentare durch und meinte, dies müsse wirklich aktualisiert werden.
Jono

4

Dies ist keine komplett neue Lösung, sondern eine Korrektur für die Lösung von afwebservant :

--note comments to see the corrections

CREATE FUNCTION [dbo].[StripHTML] (@HTMLText VARCHAR(MAX))  
RETURNS VARCHAR(MAX)  
AS  
BEGIN  
 DECLARE @Start  INT  
 DECLARE @End    INT  
 DECLARE @Length INT  
 --DECLARE @TempStr varchar(255) (this is not used)  

 SET @Start = CHARINDEX('<',@HTMLText)  
 SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))  
 SET @Length = (@End - @Start) + 1  

 WHILE @Start > 0 AND @End > 0 AND @Length > 0  
 BEGIN  
   IF (UPPER(SUBSTRING(@HTMLText, @Start, 4)) <> '<BR>') AND (UPPER(SUBSTRING(@HTMLText, @Start, 5)) <> '</BR>')  
    begin  
      SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')  
      end  
-- this ELSE and SET is important
   ELSE  
      SET @Length = 0;  

-- minus @Length here below is important
   SET @Start = CHARINDEX('<',@HTMLText, @End-@Length)  
   SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText, @Start))  
-- instead of -1 it should be +1
   SET @Length = (@End - @Start) + 1  
 END  

 RETURN RTRIM(LTRIM(@HTMLText))  
END  

Dies funktionierte für mich, nachdem ich nvarchar anstelle von varchar verwendet hatte, weil ich Unicode-Zeichen in HTML-Tags verwendete
Shadi Namrouti

3

Versuche dies. Es ist eine modifizierte Version der von RedFilter veröffentlichten ... Diese SQL entfernt alle Tags außer BR, B und P mit allen zugehörigen Attributen:

CREATE FUNCTION [dbo].[StripHtml] (@HTMLText VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
 DECLARE @Start  INT
 DECLARE @End    INT
 DECLARE @Length INT
 DECLARE @TempStr varchar(255)

 SET @Start = CHARINDEX('<',@HTMLText)
 SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText))
 SET @Length = (@End - @Start) + 1

 WHILE @Start > 0 AND @End > 0 AND @Length > 0
 BEGIN
   IF (UPPER(SUBSTRING(@HTMLText, @Start, 3)) <> '<BR') AND (UPPER(SUBSTRING(@HTMLText, @Start, 2)) <> '<P') AND (UPPER(SUBSTRING(@HTMLText, @Start, 2)) <> '<B') AND (UPPER(SUBSTRING(@HTMLText, @Start, 3)) <> '</B')
   BEGIN
      SET @HTMLText = STUFF(@HTMLText,@Start,@Length,'')
   END

   SET @Start = CHARINDEX('<',@HTMLText, @End)
   SET @End = CHARINDEX('>',@HTMLText,CHARINDEX('<',@HTMLText, @Start))
   SET @Length = (@End - @Start) - 1
 END

 RETURN RTRIM(LTRIM(@HTMLText))
END

hat bei mir nicht funktioniert SELECT dbo.StripHtml ('<b> somestuff </ b>'); gibt genau diese Zeichenfolge zurück
ladieu

@ladieu, das wird erwartet. Überprüfen Sie die allererste Zeile der Antwort ("Diese SQL entfernt alle Tags außer BR, B und P mit allen zugehörigen Attributen").
Peter Herdenborg

Diese SQL-Funktion ist falsch. Die korrigierte Funktion finden Sie in der Antwort unten.
Futureelite7

@ futureelite7 Die Verwendung von "unten" und "oben" als Referenz für die Suche nach Antworten auf einer SO-Seite ist unsinnig, da die Antwortreihenfolge über die Registerkarten oben geändert werden kann (und außerdem kann die Abstimmung die Antwortreihenfolge ändern). Bitte geben Sie eine Antwort unter Verwendung des Namens des Autors an, der sie veröffentlicht
Caius Jard

3

Wie wäre es mit XQuery mit einem Einzeiler:

DECLARE @MalformedXML xml, @StrippedText varchar(max)
SET @MalformedXML = @xml.query('for $x in //. return ($x)//text()')
SET @StrippedText = CAST(@MalformedXML as varchar(max))

Dies durchläuft alle Elemente und gibt nur den Text () zurück.

Verwenden Sie Folgendes, um zu vermeiden, dass Text zwischen Elementen ohne Leerzeichen verkettet wird:

DECLARE @MalformedXML xml, @StrippedText varchar(max)
SET @MalformedXML = @xml.query('for $x in //. return concat((($x)//text())[1]," ")')
SET @StrippedText = CAST(@MalformedXML as varchar(max))

Und um auf "Wie verwenden Sie dies für eine Spalte:

  SELECT CAST(html_column.query('for $x in //. return concat((($x)//text()) as varchar(max))
  FROM table

Stellen Sie für den obigen Code sicher, dass Sie html_columnvom Datentyp xmlsind. Wenn nicht, müssen Sie eine gegossene Version des HTML- Codes unter speichern xml. Ich würde dies als separate Übung tun, wenn Sie HTML-Daten laden, da SQL einen Fehler auslöst, wenn es fehlerhafte XML-Dateien findet, z. B. nicht übereinstimmende Start- / End-Tags oder ungültige Zeichen.

Diese eignen sich hervorragend, wenn Sie Suchphrasen erstellen, HTML entfernen usw. möchten.

Beachten Sie nur, dass dies den Typ xml zurückgibt, also CAST oder COVERT gegebenenfalls in Text umwandeln. Die XML-Version dieses Datentyps ist nutzlos, da es sich nicht um eine wohlgeformte XML-Datei handelt.


Ohne die eigentliche Lösung zum Casting aus XML halte ich dies für bestenfalls für eine Teillösung.
Dennis Jaheruddin

CAST (@xml als varchar (max)). Oder CONVERT (xml), @XML). Angenommen, die meisten Entwickler würden das herausfinden.
Arvin Amir

1
Es ist auf jeden Fall vernünftig anzunehmen, dass Entwickler wissen, wie man wirft, aber denken Sie daran, dass jemand, der Ihre Antwort liest, möglicherweise nicht direkt erkennt, dass "einfaches" Casting alles ist, was getan werden muss. Vor allem, weil erwähnt wird, dass wir gegebenenfalls gießen können . - Ich versuche nicht, negativ zu sein, hoffe nur, dass dies Ihnen bei der Erstellung von Antworten hilft, die leichter als nützlich zu erkennen sind!
Dennis Jaheruddin

Welcher Teil davon ist der Spaltenname? Nehmen wir an, ich habe eine Tabelle datamit einer Spalte namens htmlund möchte alle Werte in dieser Spalte auswählen, aber die HTML-Tags entfernen. Wie könnte ich Ihre Antwort verwenden, um dies zu erreichen?
Felix Eve

2

Hier ist eine Version, die keine UDF erfordert und auch dann funktioniert, wenn der HTML-Code Tags enthält, die nicht mit schließenden Tags übereinstimmen.

TRY_CAST(REPLACE(REPLACE(REPLACE([HtmlCol], '>', '/> '), '</', '<'), '--/>', '-->') AS XML).value('.', 'NVARCHAR(MAX)')

1

Während die Antwort von Arvin Amir einer vollständigen einzeiligen Lösung nahe kommt, können Sie überall vorbeischauen. Er hat einen kleinen Fehler in seiner select-Anweisung (das Ende der Zeile fehlt), und ich wollte die häufigsten Zeichenreferenzen behandeln.

Am Ende habe ich Folgendes gemacht:

SELECT replace(replace(replace(CAST(CAST(replace([columnNameHere], '&', '&amp;') as xml).query('for $x in //. return concat((($x)//text())[1]," ")') as varchar(max)), '&amp;', '&'), '&nbsp;', ' '), '&#x20;', ' ')
FROM [tableName]

Ohne den Zeichenreferenzcode kann dies vereinfacht werden:

SELECT CAST(CAST([columnNameHere] as xml).query('for $x in //. return concat((($x)//text())[1]," ")') as varchar(max))
FROM [tableName]

0

Der Patrick Honorez-Code muss geringfügig geändert werden.

Es werden unvollständige Ergebnisse für HTML zurückgegeben, das &lt;oder enthält&gt;

Dies liegt daran, dass der Code unter dem Abschnitt

- Entfernen Sie alles zwischen den Tags

wird in der Tat das <> zu nichts ersetzen. Die Lösung besteht darin, die folgenden zwei Zeilen am Ende anzuwenden:

set @HTMLText = replace(@htmlText, '&lt;' collate Latin1_General_CS_AS, '<'  collate Latin1_General_CS_AS)
set @HTMLText = replace(@htmlText, '&gt;' collate Latin1_General_CS_AS, '>'  collate Latin1_General_CS_AS)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.