替换重复出现的单词及其前面的字符

问题描述

我正在使用 sql Server 尝试替换字符串中每个重复出现的“[BACKSPACE]”以及单词 [BACKSPACE] 之前的字符,以模仿退格符的作用。

这是我当前的字符串: "This is a string that I would like to d[BACKSPACE]correct and see if I Could make it %[BACKSPACE] cleaner by removing the word and $[BACKSPACE] character before the backspace."

这是我想说的: "This is a string that I would like to correct and see if I Could make it cleaner by removing the word and character before the backspace."

让我更清楚地说明这一点。在上面的示例字符串中,$ 和 % 符号仅用作需要删除的字符示例,因为它们位于我要替换的 [BACKSPACE] 单词之前。

这是另一个之前的例子: The dog likq[BACKSPACE]es it's owner

我想编辑它以阅读: The dog likes it's owner

最后一个例子是: I am frequesn[BACKSPACE][BACKSPACE]nlt[BACKSPACE][BACKSPACE]tly surprised

我想编辑它以阅读: I am frequently surprised

解决方法

如果没有提供 Regex 替换的 CLR 函数,您能够做到这一点的唯一方法是在 T-SQL 中进行迭代。但是请注意,下面的解决方案不会给你你所要求的结果,而是你所要求的逻辑。您声明要删除之前的字符串和字符,但在您的两个场景中并非如此。对于最后 2 个字符串,分别删除 ' %[BACKSPACE]'' $[BACKSPACE]'(注意前导空格)。

这个前导空格留在这个解决方案中。我不想解决这个问题,因为真正的解决方案是不要为此使用 T-SQL,而使用支持 Regex 的东西。

我还假设这个字符串来自表中的一列,并且该表有多个行(每个行都有一个不同的字符串值)。

无论如何,解决方案:

WITH rCTE AS(
    SELECT V.YourColumn,STUFF(V.YourColumn,CHARINDEX('[BACKSPACE]',V.YourColumn)-1,LEN('[BACKSPACE]')+1,'') AS ReplacedColumn,1 AS Iteration
    FROM (VALUES('"This is a string that I would like to d[BACKSPACE]correct and see if I could make it %[BACKSPACE] cleaner by removing the word and $[BACKSPACE] character before the backspace."'))V(YourColumn)
    UNION ALL
    SELECT r.YourColumn,STUFF(r.ReplacedColumn,r.ReplacedColumn)-1,''),r.Iteration + 1
    FROM rCTE r
    WHERE CHARINDEX('[BACKSPACE]',r.ReplacedColumn) > 0)
SELECT TOP (1) WITH TIES
       r.YourColumn,r.ReplacedColumn
FROM rCTE r
ORDER BY ROW_NUMBER() OVER (PARTITION BY r.YourColumn ORDER BY r.Iteration DESC);

dB<>fiddle

,

我想看看是否可以使用传统的计数表方法在没有任何递归的情况下使其工作。

我认为我有一些可行的方法 - 但是递归 cte 版本绝对是一个更简洁的解决方案,并且性能可能更好,但是将其作为另一种非递归方式抛出。

/* tally table for use below */
select top 1000 N=Identity(int,1,1)
into dbo.Digits
from master.dbo.syscolumns a cross join master.dbo.syscolumns

with w as (
 select seq = Row_Number() over (order by t.N),part = Replace(Substring(@string,t.N,CharIndex(Left(@delimiter,1),@string + @delimiter,t.N) - t.N),Stuff(@delimiter,'')
 from Digits t
 where t.N <= DataLength(@string)+1 and Substring(Left(@delimiter,1) + @string,1) = Left(@delimiter,1)
),p as (
    select seq,Iif(Iif(Lead(part) over(order by seq)='' and lag(part) over(order by seq)='',0 )=1,'',Iif( seq<Max(seq) over() and part !='',Left(part,Len(part)-1),part)) part
    from w
)
select result=(
    select ''+ part
    from p
    where part!=''
    order by seq
    for xml path('')
)
,

这是一个应该可以工作的简单正则表达式模式:

/.\[BACKSPACE\]/g

编辑 我现在无法在我的 chromebook 上对此进行测试,但这似乎应该适用于 LIKE 子句中的 T-SQL

LIKE '_\[BACKSPACE]' ESCAPE '\'