SQL:从字符串中替换特定字符

时间:2013-11-07 14:16:11

标签: sql sql-server sql-server-2008

如何仅使用字符2中的1替换(12 | 2) & 23 | 4 & 25 | (6 | 7)。但不想替换21223中的25 ..

因为我不知道,字符串中有多少2。所以我只想替换2

我尝试使用replace子句但它替换了所有2

仅替换2时出现问题。

2 个答案:

答案 0 :(得分:5)

很久以前我回答了一个可能有用的问题:How to strip all non-alphabetic characters from string in SQL Server?

在那个问题中,我展示了一段在这里也很有帮助的代码(当然还有修改)。

 Declare @Temp VarChar(100)
 Set @Temp = '(12 | 2) & 23 | 4 & 25 | (6 | 7)'

 Declare @FindCharacter VarChar(10),
        @ReplaceCharacter VarChar(10)

Set @FindCharacter = '2'
Set @ReplaceCharacter = '1'

 While PATINDEX('%[^0-9]' + @FindCharacter + '[^0-9]%', @Temp) > 0
    Set @Temp = Stuff(@Temp, PATINDEX('%[^0-9]' + @FindCharacter + '[^0-9]%', @Temp) + 1, Len(@FindCharacter), @ReplaceCharacter)

Select @Temp

基本上,此代码会搜索{not a number} {value 2} {not a number}。这也意味着如果代码是字符串的第一个或最后一个字符,代码将不会替换2。这里的“替换”实际上是通过STUFF功能完成的。由于STUFF一次只能替换一个字符串,因此需要while循环才能使其多次替换。

这是一个用于替换的标量UDF。它将适应替换,即使它们位于搜索字符串的开头或结尾。

Create Function dbo.ReplaceNumber(@Input VarChar(100), @Find VarChar(10), @Replace VarChar(10))
Returns VarChar(100)
AS
Begin

    Set @Input = '~' + @Input + '~'

    While PATINDEX('%[^0-9]' + @Find + '[^0-9]%', @Input) > 0
        Set @Input = Stuff(@Input, PATINDEX('%[^0-9]' + @Find + '[^0-9]%', @Input) + 1, Len(@Find), @Replace)

    Return SubString(@Input, 2, Len(@Input)-2)
End

您可以测试/使用这样的功能:

Select dbo.ReplaceNumber('(12 | 2) & 23 | 4 & 25 | (6 | 7)','2','1')
Select dbo.ReplaceNumber('2 & 23','2','1')
Select dbo.ReplaceNumber('2 & 23','23','10')

答案 1 :(得分:1)

以下示例比较递归CTE的每个步骤的先前值,当前值和下一个值

DECLARE @text nvarchar(max) = '(12 | 2) & 23 | 4 & 25 | (6 | 7)',
        @Search nvarchar(1) = '2',
        @Repl nvarchar(1) = '1'
;WITH cte AS
  (SELECT 1 AS Number, CASE WHEN SUBSTRING (@text, 1, 1) = @Search
                            THEN @Repl ELSE SUBSTRING (@text, 1, 1) END AS Num
   UNION ALL
   SELECT c.Number + 1,
      c.Num + CASE WHEN SUBSTRING (@text, c.Number + 1, 1) = @Search
                    AND ISNUMERIC(SUBSTRING(@text, c.Number, 1)) = 0
                    AND ISNUMERIC(SUBSTRING(@text, c.Number + 2, 1)) = 0
                       THEN @Repl ELSE SUBSTRING (@text, c. Number + 1, 1) END
   FROM cte c
   WHERE Number < LEN(@text)
   )
   SELECT TOP 1 Num
   FROM cte
   ORDER BY Number DESC

SQLFiddle上的演示