วิธีที่ดีที่สุดในการถอดแท็ก html จากสตริงในเซิร์ฟเวอร์ sql?


112

ฉันมีข้อมูลใน SQL Server 2005 ที่มีแท็ก html และฉันต้องการตัดส่วนนั้นออกทั้งหมดเหลือเพียงข้อความระหว่างแท็ก ยังเป็นการดีที่จะแทนที่สิ่งต่างๆเช่น&lt;ด้วย<ฯลฯ

มีวิธีง่ายๆในการทำเช่นนี้หรือมีใครมีโค้ด t-sql ตัวอย่างแล้ว

ฉันไม่มีความสามารถในการเพิ่ม procs ที่เก็บไว้เพิ่มเติมและสิ่งที่คล้ายกันดังนั้นจึงต้องการวิธี t-sql ที่บริสุทธิ์ (โดยเฉพาะอย่างยิ่งหนึ่งย้อนหลังเข้ากันได้กับ sql 2000)

ฉันแค่ต้องการดึงข้อมูลด้วย html แบบถอดไม่ได้อัปเดตดังนั้นควรเขียนเป็นฟังก์ชันที่ผู้ใช้กำหนดเองเพื่อให้ง่ายต่อการนำมาใช้ใหม่

ตัวอย่างเช่นการแปลงสิ่งนี้:

<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>

สำหรับสิ่งนี้:

Some useful text > more text

คำตอบ:


162

มี UDF ที่จะทำตามที่อธิบายไว้ที่นี่:

ฟังก์ชันที่ผู้ใช้กำหนดเพื่อ Strip 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

แก้ไข: โปรดทราบว่านี่ใช้สำหรับ SQL Server 2005 แต่ถ้าคุณเปลี่ยนคำหลัก MAX เป็น 4000 ก็จะทำงานใน SQL Server 2000 เช่นกัน


9
เยี่ยมมากขอบคุณ ความคิดเห็นมีลิงก์ไปยังเวอร์ชันที่ปรับปรุงแล้ว: lazycoders.blogspot.com/2007/06/…ซึ่งเกี่ยวข้องกับเอนทิตี html เพิ่มเติม
รอรี

4
โปรดทราบว่าในฐานะ UDF แบบใช้สตริงมากใน SQL Server 2005 หรือใหม่กว่านี้เป็นตัวเลือกที่สมบูรณ์แบบสำหรับการใช้งานฟังก์ชัน CLR UDFสำหรับการเพิ่มประสิทธิภาพอย่างมาก ข้อมูลเพิ่มเติมเกี่ยวกับการดำเนินการที่นี่: stackoverflow.com/questions/34509/…
RedFilter

10
โปรดสังเกตว่าโพสต์ lazycoders มีการพิมพ์ผิดสองครั้ง ลบเครื่องหมายคำพูดเดี่ยวออกจากส่วนต่างๆCHAR(13) + CHAR(10)ในสองส่วนที่มีเหล่านี้ บอบบางมากพอที่ฉันจะจับมันไม่ได้จนกว่ามันจะเกินความยาวของฟิลด์สั้น ๆ (น่าสนใจและจำเป็นสำหรับฉันการแทนที่ทั้งหมดจะสั้นกว่าสตริงเดิม)
goodeye

1
สิ่งที่เกี่ยวกับค่าที่เข้ารหัส html? จะต้องมีการถอดรหัส ขอบคุณ.
JDPeckham

2
ฉันใช้ lazycoders บวกกับการแก้ไขการพิมพ์ผิดจาก @goodeye ด้านบน - ใช้งานได้ดี เพื่อประหยัดเวลา lazycoders รุ่นบล็อกอยู่ที่นี่: lazycoders.blogspot.com/2007/06/…
qxotk

18

ได้มาจากคำตอบของ @Goner Doug โดยมีการอัปเดตบางสิ่ง:
- ใช้ REPLACE หากเป็นไปได้
- การแปลงเอนทิตีที่กำหนดไว้ล่วงหน้าเช่น&eacute;(ฉันเลือกสิ่งที่ต้องการ :-)
- การแปลงแท็กรายการบางรายการ<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
ฉันเคยใช้สิ่งนี้และชอบมาก แต่ฉันได้เพิ่มการแทนที่อีกหนึ่งรายการในกลุ่มบนสุด: </p> ฉันเปลี่ยนเป็นถ่าน 13 + ถ่าน 10 ด้วยเนื่องจากท้ายแท็กย่อหน้ามักจะระบุบรรทัดใหม่ มันทำงานได้อย่างสมบูรณ์แบบในสถานการณ์เฉพาะของฉัน
DR

1
คำตอบนี้ใช้ได้ดีในส่วนใหญ่ แต่มีข้อสันนิษฐานว่าแท็ก HTML ทั้งหมดของคุณถูกต้อง ในกรณีของฉันมีปัญหาการตัดทอนในการอัปโหลด VARCHAR ที่ตัดแท็กปิดบางแท็กออกไป PATINDEX RTrim ง่ายๆทำเคล็ดลับในการลบทุกสิ่งทุกอย่าง
matt123788

2
นอกจากนี้ในการ @DR การเปลี่ยนแปลงที่ทำ (บวกอีกไม่กี่แห่งที่ผลตอบแทนการขนส่งที่จำเป็น) ผมก็ย้ายแทนที่ที่ผล<และ>ให้มากที่สุด มิฉะนั้นพวกเขาจะถูกลบด้วยแท็ก
a_hardin

8

หาก HTML ของคุณมีรูปแบบที่ดีฉันคิดว่านี่เป็นทางออกที่ดีกว่า:

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
สิ่งนี้ได้ผลสำหรับฉัน +1. แต่คุณช่วยอธิบายโค้ดของคุณเพื่อให้นักพัฒนาเข้าใจได้ง่ายขึ้นได้ไหม :)
Saeed Neamati

ดูเหมือนว่าจะโหลด html เป็นเอกสาร xml จากนั้นเลือกค่าทั้งหมดจากมัน หมายเหตุ: รหัสนี้ใช้กับ & nbsp;
JDPeckham

2
แฮ็คเพื่อไม่ให้วางระเบิดในโค้ด HTML เห็นได้ชัดว่าเป็นเพียงการแฮ็กอย่างรวดเร็วสำหรับการใช้งานภายในองค์กรหรืออะไรก็ตาม (เช่นเดียวกับ UDF ที่ยอมรับ)
dudeNumber4

ต้องมีรูปแบบที่ดีดังนั้นจึงไม่สามารถทนต่อความผิดพลาดได้เหมือนกับ RedFilter
คาห์บี

1
HTML ไม่ใช่ส่วนย่อยของ XML XHTML เป็น แต่ HTML ไม่ได้มุ่งหน้าไปตามถนนนั้นอีกต่อไป
David

7

นี่คือเวอร์ชันที่อัปเดตของฟังก์ชันนี้ซึ่งรวมเอาคำตอบ RedFilter (ต้นฉบับของ Pinal) เข้ากับการเพิ่ม LazyCoders และการแก้ไขการพิมพ์ผิดและการเพิ่มของฉันเองเพื่อจัดการ<STYLE>แท็กในบรรทัดภายใน HTML

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
สำหรับข้อมูลของฉันมีเหตุผลใดที่ใช้STUFF()แทนREPLACE()(woudl ตัวไหนที่เรียกสั้นกว่า IMO)
Patrick Honorez

ฉันไม่ได้คิดเกี่ยวกับเรื่องนี้จริงๆ ฉันแค่คัดลอก / แก้ไขต้นฉบับตามที่ระบุ การแทนที่อาจเป็นตัวเลือกที่ดีกว่า ฉันสงสัยว่ามีการเปรียบเทียบประสิทธิภาพระหว่างสองฟังก์ชั่นที่ต้องพิจารณาหรือไม่ ...
Goner Doug

1
@GonerDoug เชียร์สำหรับสิ่งนี้กำลังอ่านความคิดเห็นที่ได้รับการยอมรับว่าเป็นแบบนี้ต้องมีการอัปเดตจริงๆ
Jono

4

นี่ไม่ใช่วิธีแก้ปัญหาใหม่ที่สมบูรณ์ แต่เป็นการแก้ไขสำหรับโซลูชันของ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  

สิ่งนี้ใช้ได้ผลสำหรับฉันหลังจากที่ฉันใช้ nvarchar แทน varchar เพราะฉันใช้อักขระ unicode ในแท็ก html
Shadi Namrouti

3

ลองทำตามนี้ เป็นเวอร์ชันที่แก้ไขแล้วของเวอร์ชันที่โพสต์โดย RedFilter ... SQL นี้จะลบแท็กทั้งหมดยกเว้น BR, B และ P โดยมีแอตทริบิวต์ประกอบ:

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

ไม่ได้ผลสำหรับฉัน SELECT dbo.StripHtml ('<b> somestuff </b>'); ส่งคืนสตริงที่แน่นอน
ladieu

@ladieu นี้คาดว่า ตรวจสอบบรรทัดแรกของคำตอบ ("SQL นี้ลบแท็กทั้งหมดยกเว้น BR, B และ P พร้อมแอตทริบิวต์ประกอบ")
Peter Herdenborg

ฟังก์ชัน SQL นี้ไม่ถูกต้อง โปรดดูคำตอบด้านล่างสำหรับฟังก์ชันที่ได้รับการแก้ไข
futureelite7

@ futureelite7 โดยใช้ "ด้านล่าง" และ "ด้านบน" เป็นข้อมูลอ้างอิงสำหรับตำแหน่งที่จะค้นหาคำตอบในหน้า SO นั้นเป็นเรื่องไร้สาระเนื่องจากสามารถเปลี่ยนลำดับคำตอบได้โดยใช้แท็บด้านบน (และอื่น ๆ อีกมากมายการลงคะแนนสามารถเปลี่ยนลำดับคำตอบได้) โปรดระบุคำตอบโดยใช้ชื่อของผู้เขียนที่โพสต์
Caius Jard

3

วิธีการใช้ XQuery กับซับเดียว:

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

สิ่งนี้วนซ้ำองค์ประกอบทั้งหมดและส่งคืนข้อความ () เท่านั้น

หากต้องการหลีกเลี่ยงข้อความระหว่างองค์ประกอบที่เชื่อมต่อกันโดยไม่มีช่องว่างให้ใช้:

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))

และเพื่อตอบกลับ "คุณใช้สิ่งนี้สำหรับคอลัมน์อย่างไร:

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

สำหรับโค้ดข้างต้นให้แน่ใจว่าคุณhtml_columnเป็นประเภทข้อมูลxmlถ้าไม่คุณจำเป็นต้องบันทึกรุ่นหล่อของ html xmlที่เป็น ฉันจะทำแบบฝึกหัดแยกต่างหากเมื่อคุณโหลดข้อมูล HTML เนื่องจาก SQL จะแสดงข้อผิดพลาดหากพบ xml ที่มีรูปแบบไม่ถูกต้องเช่นแท็กเริ่มต้น / สิ้นสุดที่ไม่ตรงกันอักขระที่ไม่ถูกต้อง

สิ่งเหล่านี้ยอดเยี่ยมเมื่อคุณต้องการสร้างวลีค้นหาแถบ HTML และอื่น ๆ

โปรดทราบว่าสิ่งนี้จะส่งคืนประเภท xml ดังนั้น CAST หรือ COVERT เป็นข้อความตามความเหมาะสม เวอร์ชัน xml ของชนิดข้อมูลนี้ไม่มีประโยชน์เนื่องจากไม่ใช่ XML ที่มีรูปแบบที่ดี


หากไม่มีวิธีแก้ปัญหาจริงในการแคสต์จาก xml ฉันรู้สึกว่านี่เป็นวิธีแก้ปัญหาบางส่วนที่ดีที่สุด
Dennis Jaheruddin

CAST (@xml เป็น varchar (สูงสุด)) หรือ CONVERT (xml), @XML) สันนิษฐานว่านักพัฒนาส่วนใหญ่จะคิดออก
Arvin Amir

1
เป็นเรื่องที่สมเหตุสมผลที่จะสมมติว่านักพัฒนารู้วิธีแคสต์ แต่โปรดทราบว่าคนที่อ่านคำตอบของคุณอาจไม่เห็นโดยตรงว่าการแคสต์แบบ 'เพียง' เป็นสิ่งที่ต้องทำ โดยเฉพาะอย่างยิ่งเพราะมันบอกว่าเราสามารถโยน ที่เหมาะสม - ฉันไม่ได้พยายามมองโลกในแง่ลบเพียงแค่หวังว่านี่จะช่วยคุณในการสร้างคำตอบที่ง่ายต่อการจดจำว่าเป็นประโยชน์!
Dennis Jaheruddin

ชื่อคอลัมน์นี้คือส่วนใด? สมมติว่าฉันมีตารางที่เรียกว่าdataมีคอลัมน์ที่เรียกว่าhtmlและฉันต้องการเลือกค่าทั้งหมดในคอลัมน์นั้น แต่ตัดแท็ก html ฉันจะใช้คำตอบของคุณเพื่อให้บรรลุสิ่งนั้นได้อย่างไร
Felix Eve

3

นี่คือเวอร์ชันที่ไม่ต้องใช้ UDF และใช้งานได้แม้ว่า HTML จะมีแท็กโดยไม่ตรงกับแท็กปิดก็ตาม

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

1

ในขณะที่คำตอบของ Arvin Amir ใกล้เคียงกับโซลูชันหนึ่งบรรทัดเต็มรูปแบบที่คุณสามารถหาได้จากทุกที่ เขามีข้อบกพร่องเล็กน้อยในคำสั่งเลือก (ไม่มีท้ายบรรทัด) และฉันต้องการจัดการการอ้างอิงอักขระที่พบบ่อยที่สุด

สิ่งที่ฉันทำคือ:

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]

หากไม่มีรหัสอ้างอิงอักขระก็สามารถทำให้ง่ายขึ้นได้:

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

0

รหัส Patrick Honorez ต้องการการเปลี่ยนแปลงเล็กน้อย

ส่งคืนผลลัพธ์ที่ไม่สมบูรณ์สำหรับ html ที่มี&lt;หรือ&gt;

เนื่องจากรหัสด้านล่างส่วน

- ลบอะไรก็ได้ระหว่างแท็ก

ในความเป็นจริงจะแทนที่ <> เป็นอะไร การแก้ไขคือใช้สองบรรทัดด้านล่างในตอนท้าย:

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.