T-SQL Space Before Capital Letters

CLR and regular expressions or 26 replace statements a case sensitive collate clause and a trim.


This function combines previous answers. Selectively choose to preserve adjacent CAPS:

CREATE FUNCTION SpaceBeforeCap (
    @InputString NVARCHAR(MAX),
    @PreserveAdjacentCaps BIT
)
RETURNS NVARCHAR(MAX)
AS
BEGIN

DECLARE
    @i INT, @j INT,
        @previous NCHAR, @current NCHAR, @next NCHAR,
        @result NVARCHAR(MAX)

SELECT
    @i = 1,
        @j = LEN(@InputString),
        @result = ''

WHILE @i <= @j
BEGIN
    SELECT
        @previous = SUBSTRING(@InputString,@i-1,1),
                @current = SUBSTRING(@InputString,@i+0,1),
                @next = SUBSTRING(@InputString,@i+1,1)

    IF @current = UPPER(@current) COLLATE Latin1_General_CS_AS
    BEGIN
        -- Add space if Current is UPPER 
        -- and either Previous or Next is lower or user chose not to preserve adjacent caps
        -- and Previous or Current is not already a space
        IF @current = UPPER(@current) COLLATE Latin1_General_CS_AS
        AND (
                            @previous <> UPPER(@previous) COLLATE Latin1_General_CS_AS
                            OR  @next <> UPPER(@next) collate Latin1_General_CS_AS
                            OR  @PreserveAdjacentCaps = 0
        )
        AND @previous <> ' '
        AND @current <> ' '
            SET @result = @result + ' '
    END 

    SET @result = @result + @current
    SET @i = @i + 1
END 

RETURN @result
END

GO
SELECT dbo.SpaceBeforeCap('ThisIsASampleDBString', 1)
GO
SELECT dbo.SpaceBeforeCap('ThisIsASampleDBString', 0)

Assuming SQL Server 2005 or later, this modified from code taken here: http://www.kodyaz.com/articles/case-sensitive-sql-split-function.aspx

CREATE FUNCTION SpaceBeforeCap
(
 @str nvarchar(max)
)
returns nvarchar(max)
as
begin

declare @i int, @j int
declare @returnval nvarchar(max)
set @returnval = ''
select @i = 1, @j = len(@str)

declare @w nvarchar(max)

while @i <= @j
begin
 if substring(@str,@i,1) = UPPER(substring(@str,@i,1)) collate Latin1_General_CS_AS
 begin
  if @w is not null
  set @returnval = @returnval + ' ' + @w
  set @w = substring(@str,@i,1)
 end
 else
  set @w = @w + substring(@str,@i,1)
 set @i = @i + 1
end
if @w is not null
 set @returnval = @returnval + ' ' + @w

return ltrim(@returnval)

end

This can then be called just as you have suggested above.


This will add spaces only if the previous and next character is lowercase. That way 'MyABCAnalysis' will be 'My ABC Analysis'.

I added a check for a previous space too. Since some of our strings are prefixed with 'GR_' and some also contain underscores, we can use the replace function as follows:

select dbo.GR_SpaceBeforeCap(replace('GR_ABCAnalysis_Test','_',' ')) Returns 'GR ABC Analysis Test'

CREATE FUNCTION GR_SpaceBeforeCap (
    @str nvarchar(max)
)
returns nvarchar(max)
as
begin

declare
    @i int, @j int
,   @cp nchar, @c0 nchar, @c1 nchar
,   @result nvarchar(max)

select
    @i = 1
,   @j = len(@str)
,   @result = ''

while @i <= @j
begin
    select
        @cp = substring(@str,@i-1,1)
    ,   @c0 = substring(@str,@i+0,1)
    ,   @c1 = substring(@str,@i+1,1)

    if @c0 = UPPER(@c0) collate Latin1_General_CS_AS
    begin
        -- Add space if Current is UPPER 
        -- and either Previous or Next is lower
        -- and Previous or Current is not already a space
        if @c0 = UPPER(@c0) collate Latin1_General_CS_AS
        and (
                @cp <> UPPER(@cp) collate Latin1_General_CS_AS
            or  @c1 <> UPPER(@c1) collate Latin1_General_CS_AS
        )
        and @cp <> ' '
        and @c0 <> ' '
            set @result = @result + ' '
    end -- if @co

    set @result = @result + @c0
    set @i = @i + 1
end -- while

return @result
end

Tags:

Tsql