【问题标题】:How to strip HTML tags from a string in SQL Server?如何从 SQL Server 中的字符串中去除 HTML 标签?
【发布时间】:2010-10-02 05:51:23
【问题描述】:

我在 SQL Server 2005 中有包含 HTML 标记的数据,我想去掉所有这些,只留下标记之间的文本。理想情况下,还可以将 < 替换为 < 等。

有没有一种简单的方法可以做到这一点,或者有人已经得到了一些示例 T-SQL 代码?

我没有能力添加扩展存储过程等,因此更喜欢纯 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

【问题讨论】:

    标签: html sql sql-server string sql-server-2005


    【解决方案1】:

    有一个 UDF 可以执行此处描述的操作:

    User Defined Function to 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 中使用。

    【讨论】:

    • 太好了,谢谢。那里的评论链接到一个改进的版本:lazycoders.blogspot.com/2007/06/…,它处理更多的 html 实体。
    • 请注意,作为 SQL Server 2005 或更高版本中的字符串密集型 UDF,这是实现 CLR UDF 函数的理想候选者,可大幅提升性能。有关这样做的更多信息:stackoverflow.com/questions/34509/…
    • 请注意,lazycoders 的帖子有两个错别字。在包含这些的两个部分中删除 CHAR(13) + CHAR(10) 周围的单引号。足够微妙,直到它超过一个短字段的长度,我才抓住它(有趣的是,对我来说,所有替换都比原始字符串短)。
    • html 编码值呢?需要他们解码。谢谢。
    • 我使用了lazycoders,加上上面@goodeye 的错字修复——效果很好。为了节省时间,lazycoders 博客版本在这里:lazycoders.blogspot.com/2007/06/…
    【解决方案2】:

    如果您的 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。但是您能否解释一下您的代码,以便开发人员更容易理解它? :)
    • 它看起来像是将 html 作为 xml 文档加载,然后从中选择所有值。注意:此代码在  
    • 为了不轰炸 HTML 代码而设置一个 hack。显然只是内部使用或其他任何东西的快速破解(就像公认的 UDF 一样)。
    • 它必须是良好的格式,所以它不像 RedFilter 那样容错。
    • HTML 不是 XML 的子集。 XHTML 是,但 HTML 不再走这条路了。
    【解决方案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('somestuff');返回那个确切的字符串
    • @ladieu,这是意料之中的。检查答案的第一行(“此 SQL 删除除 BR、B 和 P 之外的所有标签以及任何附带的属性”)。
    • 这个 SQL 函数不正确。修正后的功能请参考下面的答案。
    • @futureelite7 使用“下方”和“上方”作为在 SO 页面上何处查找答案的参考是荒谬的,因为可以使用顶部的选项卡更改答案顺序(以及更多,投票可以改变答案顺序)。请使用发布者的姓名指定答案
    【解决方案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 之后,这对我有用,因为我在 html 标签中使用了 unicode 字符
    【解决方案5】:

    这是此函数的更新版本,其中包含 RedFilter answer(Pinal 的原始版本)与 LazyCoders 添加和 goodeye 错字更正以及我自己添加的用于处理 HTML 内的内联 &lt;STYLE&gt; 标签。

    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
    

    【讨论】:

    • 据我所知,有什么理由使用 STUFF() 而不是 REPLACE() (哪个会更短 IMO)?
    • 我并没有真正考虑过。如图所示,我只是复制/修改了原件。替换可能是一个更好的选择。我想知道是否有两个函数之间的性能比较要考虑...
    • @GonerDoug 为此欢呼,正在阅读接受的 cmets,这确实需要更新。
    【解决方案6】:

    源自@Goner Doug 的回答,更新了一些内容:
    - 尽可能使用 REPLACE
    - 预定义实体的转换,例如 &amp;eacute;(我选择了我需要的实体 :-)
    - 列表标签的一些转换&lt;ul&gt; and &lt;li&gt;

    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
    

    【讨论】:

    • 我已经使用过并且喜欢它,但我确实在顶部组中添加了一个替换: 我也更改为 char 13 + char 10 也因为段落标签的结尾通常会指示一个新行。它在我的特定场景中完美运行
    • 这个答案在大多数情况下都很好用,但假设您的所有 HTML 标记都是有效的。就我而言,VARCHAR 上传存在截断问题,消除了一些结束标签。一个简单的 PATINDEX RTrim 就可以删除其他所有内容。
    • 除了更改@D.R.制作(加上更多需要回车的),我还将导致&lt;和&gt;的替换移到最后。否则他们会被标签一起删除。
    • 我在第一个块中添加了以下行:set @HTMLText = replace(@htmlText, '&amp;#x0D;',CHAR(13) + CHAR(10))
    【解决方案7】:

    如何将 XQuery 与单列一起使用:

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

    这将遍历所有元素并仅返回 text()。

    要避免元素之间的文本没有空格连接,请使用:

    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 转换的实际解决方案,我觉得这充其量只是部分解决方案。
    • CAST(@xml as varchar(max))。或转换(xml),@XML)。假设大多数开发人员都知道这一点。
    • 假设开发人员知道如何投射绝对是合理的,但请记住,阅读您的答案的人可能不会直接看到“简单”投射就是需要完成的全部工作。特别是因为提到我们可以在适当的地方进行。 -- 我并不是要否定,只是希望这可以帮助您创建更容易识别为有用的答案!
    • 那么列名是哪一部分?假设我有一个名为 data 的表,其中有一列名为 html,我想选择该列中的所有值,但去掉 html 标签,我该如何使用您的答案来实现这一目标?
    【解决方案8】:

    Patrick Honorez 代码需要稍作改动。

    它返回包含&amp;lt; 或&amp;gt; 的html 的不完整结果

    这是因为该部分下面的代码

    -- 删除标签之间的任何内容

    实际上会将 替换为空。解决方法是在末尾应用以下两行:

    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)
    

    【讨论】:

      【解决方案9】:

      这是一个不需要 UDF 的版本,即使 HTML 包含没有匹配结束标签的标签也可以工作。

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

      【讨论】:

      • 我无法使用原始问题中的示例 HTML 使此方法起作用。
      • 这在
        和
        和 和 上中断
      【解决方案10】:

      虽然 Arvin Amir 的答案接近于一个完整的单线解决方案,但您可以在任何地方使用;他的 select 语句中有一个小错误(缺少行尾),我想处理最常见的字符引用。

      我最终做的是:

      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]
      

      【讨论】:

        【解决方案11】:

        如果您不想使用 UDF 功能,请尝试此操作。

        SELECT COLUMN1, TRY_CONVERT(xml, COLUMN2).value('.', 'nvarchar(max)') as COL2, COLUMN3
        FROM   DBO.TABLENAME        
        

        【讨论】:

        • 我无法得到这个答案来处理像&lt;font color=black&gt;&lt;font color=navy&gt;&lt;b&gt;SELECT&lt;/b&gt;&lt;/font&gt; *&lt;BR&gt;&lt;font color=navy&gt;&lt;b&gt;FROM&lt;/b&gt;&lt;/font&gt; Table&lt;font&gt;这样的简单查询
        猜你喜欢
        • 2014-11-16
        • 2012-08-07
        • 1970-01-01
        • 2012-06-06
        • 2011-06-27
        • 2011-05-24
        • 2010-10-21
        • 2020-10-11
        相关资源
        最近更新 更多