在T-SQL中用一个空格替换重复的空格

Chr*_*oph 95 t-sql sql-server

我需要确保一个给定的字段在字符之间没有多个空格(我不关心所有空格,只关心空格).

所以

'single    spaces   only'
Run Code Online (Sandbox Code Playgroud)

需要变成

'single spaces only'
Run Code Online (Sandbox Code Playgroud)

以下不起作用

select replace('single    spaces   only','  ',' ')
Run Code Online (Sandbox Code Playgroud)

因为它会导致

'single  spaces  only'
Run Code Online (Sandbox Code Playgroud)

我更喜欢坚持使用原生T-SQL而不是基于CLR的解决方案.

思考?

Nei*_*ght 295

更整洁:

select string = replace(replace(replace(' select   single       spaces',' ','<>'),'><',''),'<>',' ')
Run Code Online (Sandbox Code Playgroud)

输出:

选择单个空格

  • Chris,您可以使用不可打印的ASCII字符,如CHAR(17)和CHAR(18),因为这些字符永远不会出现在您的输入文本中.仍然比接受答案的循环更快. (28认同)
  • 真正优雅的黑客.Upvoted.如果<>可能在输入文本中,则任何两个字符都可以用于中间部分. (8认同)
  • 如果要删除字符串前端和末尾的空格,请将替换包装在LTRIM,RTRIM中,它会为您完成. (6认同)
  • @AnthonyGriggs,我猜你的意思是使用以下表达式:`REPLACE(REPLACE(REPLACE(YOUR_COLUMN_NAME, ' ', CHAR(17)+CHAR(18)), CHAR(18)+CHAR(17), '') , CHAR(17)+CHAR(18), ' ')` (5认同)
  • 只要你的字符串不包含很多<或>符号.似乎对我来说很脆弱. (4认同)
  • 我必须真正看一下这一刻才能弄清楚你使用了'> <',''没有替换空间但现在我明白了......它非常精彩.我非常喜欢@richardtallent建议使用不可打印的ASCII字符,其中添加的组合产生:REPLACE(REPLACE(REPLACE(LastName,'','CHAR(17)CHAR(18)'),'CHAR(18 )CHAR(17)',''),'CHAR(17)CHAR(18)','') (4认同)
  • @AnthonyGriggs 我会 [你的评论](//stackoverflow.com/q/2455750#comment49833480_2455869) 因为我有`&lt;&gt;` 需要维护,所以我使用了你的例子并且它有效。**但后来我意识到**(就像我在之前的评论中向非信徒建议的那样分解它)您的 SQL 没有按照您的想法执行:`...'CHAR(17)CHAR(18)'...` 替换使用 *** 文本字符串***,而不是 ASCII 字符——这很有趣,*有效*——但出于同样的原因`QQQQQQ`和`ZZZZZZ`也可以:它们也不太可能在字符串。我会用更多信息添加到答案中。 (4认同)
  • @sam 他使用 `&gt;&lt;` 和 `&lt;&gt;` 的原因确实非常出色。您最终会得到一个类似于“&lt;&gt;&lt;&gt;&lt;&gt;&lt;&gt;&lt;&gt;&lt;&gt;”的字符串,单词之间的字符串可能更长或更短,具体取决于第一次替换的空格数量。第二次替换获取每个字符串并将它们压缩为“&lt;&gt;”。最后第三次替换将每个“&lt;&gt;”变成一个空格。显然,这里的问题是任何包含 XML 的字符串都无法使用此方法,但正如其他一些人指出的那样,您可以使用无法在其位置打印的 ASCII 字符 (2认同)

Jam*_*man 25

这可行:

declare @test varchar(100)
set @test = 'this   is  a    test'

while charindex('  ',@test  ) > 0
begin
   set @test = replace(@test, '  ', ' ')
end

select @test
Run Code Online (Sandbox Code Playgroud)

  • 包装函数并将 varchar(100) 更改为 nvarchar(max) (2认同)
  • 通过 50k 记录运行它应该快如闪电,如果这是你的问题,我会研究其他问题。 (2认同)

Bra*_*adC 16

如果您知道连续的空格不会超过一定数量,则可以嵌套替换:

replace(replace(replace(replace(myText,'  ',' '),'  ',' '),'  ',' '),'  ',' ')
Run Code Online (Sandbox Code Playgroud)

4个替换应该最多固定16个空格(16个,然后是8个,然后是4个,然后是2个,然后是1个)

如果它可能显着更长,那么你必须做一些像内联函数:

CREATE FUNCTION strip_spaces(@str varchar(8000))
RETURNS varchar(8000) AS
BEGIN 
    WHILE CHARINDEX('  ', @str) > 0 
        SET @str = REPLACE(@str, '  ', ' ')

    RETURN @str
END
Run Code Online (Sandbox Code Playgroud)

然后就做

SELECT dbo.strip_spaces(myText) FROM myTable
Run Code Online (Sandbox Code Playgroud)


HLG*_*GEM 6

update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 
Run Code Online (Sandbox Code Playgroud)

替换将适用于所有双空格,无需多次替换.这是基于集合的解决方案.


Ada*_*nko 6

它可以通过函数递归完成:

CREATE FUNCTION dbo.RemSpaceFromStr(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS
BEGIN
  RETURN (CASE WHEN CHARINDEX('  ', @str) > 0 THEN
    dbo.RemSpaceFromStr(REPLACE(@str, '  ', ' ')) ELSE @str END);
END
Run Code Online (Sandbox Code Playgroud)

然后,例如:

SELECT dbo.RemSpaceFromStr('some   string    with         many     spaces') AS NewStr
Run Code Online (Sandbox Code Playgroud)

返回:

NewStr
some string with many spaces
Run Code Online (Sandbox Code Playgroud)

或者基于@agdk26 或@Neil Knight(但更安全)描述的方法的解决方案(但更安全)
两个示例都返回上面的输出:

SELECT REPLACE(REPLACE(REPLACE('some   string    with         many     spaces'
  , '  ', ' ' + CHAR(7)), CHAR(7) + ' ', ''), ' ' + CHAR(7), ' ') AS NewStr 
--but it remove CHAR(7) (Bell) from string if exists...
Run Code Online (Sandbox Code Playgroud)

或者

SELECT REPLACE(REPLACE(REPLACE('some   string    with         many     spaces'
  , '  ', ' ' + CHAR(7) + CHAR(7)), CHAR(7) + CHAR(7) + ' ', ''), ' ' + CHAR(7) + CHAR(7), ' ') AS NewStr
--but it remove CHAR(7) + CHAR(7) from string
Run Code Online (Sandbox Code Playgroud)

这个怎么运作: 在此处输入图片说明

注意:
用于替换空格的字符/字符串不应存在于字符串的开头或结尾并且是独立的。


Joh*_*nFx 5

这有点蛮力,但会起作用

CREATE FUNCTION stripDoubleSpaces(@prmSource varchar(max)) Returns varchar(max)
AS 
BEGIN
    WHILE (PATINDEX('%  %', @prmSource)>0)
     BEGIN
        SET @prmSource = replace(@prmSource  ,'  ',' ')
     END

    RETURN @prmSource
END

GO

-- Unit test -- 
PRINT dbo.stripDoubleSpaces('single    spaces   only')

single spaces only
Run Code Online (Sandbox Code Playgroud)


小智 5

这是我创建的一个简单函数,用于清除字符串之前或之后的任何空格以及字符串中的多个空格。它可以优雅地处理单次拉伸中最多大约 108 个空格以及字符串中尽可能多的块。如果需要,您可以通过添加具有更大空间块的附加行来将其增加 8 倍。尽管它在大型应用程序中得到广泛使用,但它似乎执行得很快并且没有造成任何问题。

CREATE FUNCTION [dbo].[fnReplaceMultipleSpaces] (@StrVal AS VARCHAR(4000)) 
RETURNS VARCHAR(4000) 
AS 
BEGIN

    SET @StrVal = Ltrim(@StrVal)
    SET @StrVal = Rtrim(@StrVal)

    SET @StrVal = REPLACE(@StrVal, '                ', ' ')  -- 16 spaces
    SET @StrVal = REPLACE(@StrVal, '        ', ' ')  -- 8 spaces
    SET @StrVal = REPLACE(@StrVal, '    ', ' ')  -- 4 spaces
    SET @StrVal = REPLACE(@StrVal, '  ', ' ')  -- 2 spaces
    SET @StrVal = REPLACE(@StrVal, '  ', ' ')  -- 2 spaces (for odd leftovers)

RETURN @StrVal

END
Run Code Online (Sandbox Code Playgroud)