Заменить дублирующиеся пробелы одним пространством в T-SQL

Мне нужно убедиться, что в заданном поле не более одного пространства (меня не интересует все пробел, просто пробел) между символами.

Итак,

'single    spaces   only'

необходимо преобразовать в

'single spaces only'

Ниже не будет работать

select replace('single    spaces   only','  ',' ')

поскольку это приведет к

'single  spaces  only'

Я бы предпочел использовать собственный T-SQL, а не решение на основе CLR.

Мысли?

Ответ 1

Даже более аккуратный:

select string = replace(replace(replace(' select   single       spaces',' ','<>'),'><',''),'<>',' ')

Вывод:

выберите отдельные пробелы

Ответ 2

Это будет работать:

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

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

select @test

Ответ 3

Если вы знаете, что не должно быть больше определенного количества пробелов в строке, вы можете просто вложить замену:

replace(replace(replace(replace(myText,'  ',' '),'  ',' '),'  ',' '),'  ',' ')

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

Тогда просто сделайте

SELECT dbo.strip_spaces(myText) FROM myTable

Ответ 4

update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 

Заменить будет работать во всех двойных пространствах, не нужно ставить несколько замен. Это решение на основе набора.

Ответ 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

Ответ 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

тогда, например:

SELECT dbo.RemSpaceFromStr('some   string    with         many     spaces') AS NewStr

возвращает:

NewStr
some string with many spaces

Или решение, основанное на методе, описанном @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...

или же

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

Как это работает: enter image description here

Внимание:
Символ/строка, используемые для замены пробелов, не должны существовать в начале или конце строки и стоять отдельно.

Ответ 7

Вот простая функция, которую я создал для очистки пробелов до или после, и несколько пробелов внутри строки. Он грациозно обрабатывает до 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

Ответ 8

Это решение через множественную замену, которая работает для любых строк (не требует специальных символов, которые не являются частью строки).

declare @value varchar(max)
declare @result varchar(max)
set @value = 'alpha   beta gamma  delta       xyz'

set @result = replace(replace(replace(replace(replace(replace(replace(
  @value,'a','ac'),'x','ab'),'  ',' x'),'x ',''),'x',''),'ab','x'),'ac','a')

select @result -- 'alpha beta gamma delta xyz'

Ответ 9

Нашел это, копая для ответа:

SELECT REPLACE(
        REPLACE(
             REPLACE(
                LTRIM(RTRIM('1 2  3   4    5     6'))
            ,'  ',' '+CHAR(7))
        ,CHAR(7)+' ','')
    ,CHAR(7),'') AS CleanString
where charindex('  ', '1 2  3   4    5     6') > 0

Полный ответ (с объяснением) был вырван из: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html

При втором взгляде кажется немного отличающейся версией выбранного ответа.

Ответ 10

Метод # 1

Первый способ - заменить лишние пробелы между словами с необычной символической комбинацией в качестве временного маркера. Затем вы можете заменить временные символы маркера, используя функцию replace, а не цикл.

Вот пример кода, который заменяет текст в переменной String.

DECLARE @testString AS VARCHAR(256) = ' Test        text   with  random*        spacing. Please normalize  this spacing!';
SELECT REPLACE(REPLACE(REPLACE(@testString, ' ', '*^'), '^*', ''), '*^', ' ');

Время выполнения выполнения №1: в десяти прогонах этого метода замены среднее время ожидания ответов сервера составляло 1,7 миллисекунды, а общее время выполнения составляло 4,6 миллисекунды. Время выполнения теста №2: среднее время ожидания ответов сервера составляло 1,7 миллисекунды, а общее время выполнения составляло 3,7 миллисекунды.

Метод # 2

Второй метод не столь изящный, как первый, но и выполняет свою работу. Этот метод работает путем вложения четырех (или необязательно большего) замещающих операторов, которые заменяют два пробела одним пробелом.

DECLARE @testString AS VARCHAR(256) = ' Test        text   with  random*        spacing. Please normalize  this spacing!';
SELECT REPLACE(REPLACE(REPLACE(REPLACE(@testString,' ',' '),' ',' '),' ',' '),' ',' ')

Тест времени выполнения # 1: в десяти прогонах этого метода замены среднее время ожидания ответов сервера составляло 1,9 миллисекунды, а общее время выполнения составляло 3,8 миллисекунды. Время выполнения теста №2: среднее время ожидания ответов сервера составляло 1,8 миллисекунды, а общее время выполнения составляло 4,8 миллисекунды.

Метод № 3

Третий способ замены лишних пробелов между словами - использовать простой цикл. Вы можете выполнить проверку дополнительных пробелов в цикле while, а затем использовать функцию replace, чтобы уменьшить дополнительные пробелы с каждой итерацией цикла.

DECLARE @testString AS VARCHAR(256) = ' Test text with random* spacing. Please normalize this spacing!';
WHILE CHARINDEX(' ',@testString) > 0
SET @testString = REPLACE(@testString, ' ', ' ')
SELECT @testString

Тест времени выполнения # 1: в десяти прогонах этого метода замены среднее время ожидания ответов сервера составляло 1,8 миллисекунды, а общее время выполнения составляло 3,4 миллисекунды. Время выполнения теста №2: среднее время ожидания ответов сервера составляло 1,9 миллисекунды, а общее время выполнения составляло 2,8 миллисекунды.

Ответ 11

Я использую решение FOR XML PATH для замены нескольких пробелов в один пробел

Идея состоит в том, чтобы заменить пробелы тегами XML. Затем разбить строку XML на строковые фрагменты без тегов XML. Наконец, объединить эти строковые значения, добавив один пробел между двумя

Вот как можно вызывать финальную функцию UDF

select dbo.ReplaceMultipleSpaces('   Sample   text  with  multiple  space     ')

Ответ 12

 DECLARE @str varchar(150)
SET @str='Hello    My   name  is Jiyaul   mustafa'
Select REPLACE(REPLACE(REPLACE(@str,' ','{}'),'}{',''),'{}',' ')

Ответ 13

Я обычно использую этот подход:

declare @s varchar(50)
set @s = 'TEST         TEST'
select REPLACE(REPLACE(REPLACE(@s,' ','[o][c]'),'[c][o]',''),'[o][c]',' ')

Ответ 14

Вы можете попробовать следующее:

select Regexp_Replace('single    spaces   only','( ){2,}', ' ') from dual;

Ответ 15

update mytable
set myfield = replace(myfield, '  ',  ' ')
where myfield like '%  %'

Попробуйте это.