替换sql server中特定单词之间的文本

时间:2015-08-19 07:41:08

标签: sql sql-server sql-server-2008 sql-server-2008-r2 sql-server-2012

我的nvarchar(max)类型列。 它有html文本作为字符串。像吼叫一样。

<a>hi_this </a>
<i>is_sample</i>
<p>text_data</P>
<a>in_column</a>
<p>this_is_paragraph</p>
<a>this_is_end</a>

无论如何,顶部替换标记_<p>之间的下划线(</p>)符号

所以我希望最终输出像下面一样。

<a>hi_this </a>
<i>is_sample</i>
<p>text data</P>
<a>in_column</a>
<p>this is paragraph</p>
<a>this_is_end</a>

有可能吗?

更新的 它是这样的单排。 &#39;&LT; a&gt; hi_this&lt; / a&gt;&lt; i&gt; is_sample&lt; / i&gt;&lt; p>文本数据&lt; / P&gt;&lt; a&gt; in_column&lt; / a&gt; &LT; p>这是段落&lt; / p&gt; &LT; a&gt; this_is_end&lt; / a&gt;&#39;

3 个答案:

答案 0 :(得分:2)

为什么不使用简单的REPLACE功能

update my_table
set path = replace(path, '_', ' ')
WHERE path like '<p>%'

答案 1 :(得分:2)

我真的不认为SQL是最好的工具,但我做了一些似乎适用于你的情况。第一步是建立一个数字表。如果你已经拥有了那么好,请使用它,但为了得到一个完整的答案,我认为你没有。

只需使用table value constructor创建一个包含10行(N1)的表格,然后将其与自身交叉连接以获得100行(N3),然后交叉即可完成此操作将其与自身连接以获得10,000行(Numbers)的表格,然后使用ROW_NUMBER()获取每行1-10,000的数字:

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N2 AS N1 CROSS JOIN N2 AS N2)

SELECT  *
FROM    Numbers;

可以在Generate a set or sequence without loops系列中找到关于此问题的进一步阅读以及其他这样做的方法。如果您需要超过10,000个数字,只需添加更多交叉连接,直到您有足够的

获得数字表后,您可以使用SUBSTRING()来确定所有开放<p>代码的位置,使用“

DECLARE @S NVARCHAR(500) = '
    <a>hi_this </a>
    <i>is_sample</i>
    <p>text_data</P>
    <a>in_column</a>
    <p>this_is_paragraph</p>
    <a>this_is_end</a>';

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N2 AS N1 CROSS JOIN N2 AS N2)

SELECT  OriginalString = SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4),
        Start = Number,
        NumChars = CHARINDEX('</p>', @s, Number + 1) - Number + 4,
        NewString = REPLACE(SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4), '_', ' ')
FROM    Numbers
WHERE   SUBSTRING(@S, Number, 3) = '<p>';

结果:

OriginalString              Start       NumChars    NewString
---------------------------------------------------------------------------
<p>text_data</P>            40          16          <p>text data</P>
<p>this_is_paragraph</p>    80          24          <p>this is paragraph</p>

您可以使用SUBSTRING(@S, Number, 3) = '<p>'获取每个p代码的起始位置,然后使用CHARINDEX()获取下一个结束p代码的位置,以及替换之间的文本。

最后,您需要使用此输出替换原始字符串,您可以使用STUFF()执行此操作:

DECLARE @S NVARCHAR(500) = '
    <a>hi_this </a>
    <i>is_sample</i>
    <p>text_data</P>
    <a>in_column</a>
    <p>this_is_paragraph</p>
    <a>this_is_end</a>';

WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
Numbers (Number) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N2 AS N1 CROSS JOIN N2 AS N2),
Data AS
(   SELECT  OriginalString = SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4),
            Start = Number,
            NumChars = CHARINDEX('</p>', @s, Number + 1) - Number + 4,
            NewString = REPLACE(SUBSTRING(@S, Number, CHARINDEX('</p>', @s, Number + 1) - Number + 4), '_', ' ')
    FROM    Numbers
    WHERE   SUBSTRING(@S, Number, 3) = '<p>'
)
SELECT  @S = STUFF(@S, Start, NumChars, NewString)
FROM    Data;

PRINT @S;

给出了:

    <a>hi_this </a>
    <i>is_sample</i>
    <p>text data</P>
    <a>in_column</a>
    <p>this is paragraph</p>
    <a>this_is_end</a>

答案 2 :(得分:0)

您可以在REPLACE中使用CASE

SELECT CASE 
          WHEN col LIKE '<p>%' AND col LIKE '%</p>' THEN REPLACE(col, '_', ' ') 
          ELSE col 
       END AS col
FROM #table1

<强>输出

<a>hi_this </a>
<i>is_sample</i>
<p>text data</P>
<a>in_column</a>
<p>this is paragraph</p>
<a>this_is_end</a>

SQL FIDDLE

<强>更新

如您所愿,这会将结果集合并为1行:

DECLARE @combine VARCHAR(MAX)

;WITH cte AS (
   SELECT CASE WHEN col LIKE '<p>%' and col LIKE '%</p>' THEN REPLACE(col, '_', ' ') ELSE col END AS col
   FROM table1
)
SELECT @combine = COALESCE(@combine, ' ') + col
FROM cte
SELECT @combine as col 

<强>输出

 <a>hi_this </a><i>is_sample</i><p>text data</P><a>in_column</a><p>this is paragraph</p><a>this_is_end</a>

<强> SQL FIDDLE