首页 > 解决方案 > 如果前面没有相同的字符,则替换字符

问题描述

我试图通过将单个替换为以下斜杠来逃避一些\反斜杠\\

UPDATE Table
SET Column = REPLACE(Column , '\', '\\')

但是我只想在反斜杠之前没有另一个反斜杠时才进行替换,因此输入test\应该替换为test\\test\\应该保留test\\

如果存在两个以上的反斜杠,则也不应该替换。

标签: sqlsql-servertsql

解决方案


T-SQL 不支持模式替换,所以你需要在REPLACE这里使用一些嵌套的 s;第一个将双斜杠 ( \\) 替换为您的数据中未出现的内容(我使用管道 ( |)),第二个替换单斜杠,最后第三个将管道替换为双斜杠。

UPDATE dbo.[Table]
SET [Column] = REPLACE(REPLACE(REPLACE([Column], '\\', '|'),'\','\\'),'|','\\');

如果您有这样的值,则以'test\\\'结尾'test\\\\',因为前 2 个\字符不会被替换,但后者会。


由于我是一个“贪婪的惩罚者”,如果您确实需要避免上述'\\\'被替换为'\\\\' 并且(因为您没有提及)可能在您的值中有多个单斜杠实例,您将不得不做类似的事情这个。

CREATE TABLE dbo.[Table] (ID int IDENTITY, --As I assume you have some kind of ID column
                         [Column] varchar(100));
GO
INSERT INTO dbo.[Table] ([Column])
VALUES ('test\'),
       ('sample\\'),
       ('example\\\'),
       ('Another\example'),
       ('A\harder\\example\'),
       ('A\far\\more\complex\\example\\\than\is\\needed\');
GO
SELECT *
FROM dbo.[Table];
GO
WITH rCTE AS(
    SELECT T.ID,
           T.[Column],
           PI.I,
           STUFF(T.[Column],PI.I+1,0,'\') AS NewColumn,
           1 AS Iteration
    FROM dbo.[Table] T
         CROSS APPLY (VALUES(PATINDEX('%[^\]\[^\]%',[Column])))PI(I)
    UNION ALL
    SELECT r.ID,
           r.[Column],
           PI.I,
           LEFT(r.NewColumn,r.I+1) + STUFF(S.StuffColumn,PI.I+1,0,'\') AS NewColumn,
           r.Iteration+1 AS Iteration
    FROM rCTE r
         CROSS APPLY (VALUES(STUFF(r.NewColumn,1,r.I+1,'')))S(StuffColumn)
         CROSS APPLY (VALUES(PATINDEX('%[^\]\[^\]%',StuffColumn)))PI(I)
    WHERE PI.I > 0)
UPDATE T
SET [Column] = CASE WHEN r.NewColumn LIKE '%[^\]\' THEN r.NewColumn + '\' ELSE r.NewColumn END
FROM dbo.[table] T
     CROSS APPLY (SELECT TOP (1)
                         CASE WHEN r.NewColumn LIKE '%[^\]\' THEN r.NewColumn + '\' ELSE r.NewColumn END AS NewColumn
                  FROM rCTE r
                  WHERE r.ID = T.ID
                  ORDER BY r.Iteration DESC) r;
GO

SELECT *
FROM dbo.[Table];

在这里,我们必须使用递归 CTE 来迭代该值,并且每次它找到一个\没有另一个斜杠相邻的斜杠 ( ) 时,它都会将另一个斜杠注入到字符串中。然后,由于这在字符串的末尾不起作用,您需要使用CASE表达式将值添加到末尾的额外斜杠。您还需要一开始就这样做(但我在这里没有这样做)。

db<>小提琴


推荐阅读