修剪空白而不影响内部空白

时间:2014-09-28 23:46:57

标签: sql sql-server string tsql

我需要从字符串修剪空格(包括制表符,换行符等),而不会影响内部空白。例如:



foo
bar
    baz
    

会变成

foo
bar
    baz

当然LTRIM / RTRIM不够用,因为它们只删除了空格。这里有一些帖子显示使用REPLACE方法处理其他字符(例如this one),但当然也会删除内部字符。我在这里找不到一个例子来展示如何从字符串中仅删除前导和尾随空白字符。

6 个答案:

答案 0 :(得分:1)

SQLCLR可以轻松处理此功能。您可以编写自己的函数来执行简单的String.Trim(),也可以下载已编写的函数,例如SQL#库中的String_Trim()函数。我是SQL#的作者,但免费版本中提供了String_Trim函数(以及许多其他函数,包括正则表达式等)。

String_Trim()从字符串的两端删除空格(制表符,换行符,回车符和空格),而不触及非空白字符之间的任何空格。如果您复制并粘贴下面的示例代码,您将看到非空白字符之前和之后以及它们之间是每种类型的空白字符的混合(好吧,标签在这里被转换为空格所以我有明确地放入标签。)

这很简单:

PRINT N'~~' + SQL#.String_Trim(N'   ' + NCHAR(9) + N'   
    ' + NCHAR(9) + N'   gfgj    
lf      ' + NCHAR(9) + N'      

g  

' + NCHAR(9) + N'       g        
    ' + NCHAR(9) + N'   ') + N'~~';

输出:

~~gfgj  
lf             

g

    g~~

答案 1 :(得分:0)

这是我目前的解决方案,但我欢迎其他建议。对于VARCHAR值:

DECLARE @str varchar(8000) , 
        @pat varchar(100) = '%[^ ' + CHAR(9) + '-' + CHAR(13) + ']%';

SET @str = /* load value */

SET @str = SUBSTRING( @str , PATINDEX( @pat , @str ) , 
        DATALENGTH( @str ) - 
        PATINDEX( @pat , @str ) - 
        PATINDEX( @pat , REVERSE( @str )) + 2 );

但由于NVARCHAR个字符占用2个字节,因此在这种情况下,您需要将DATALENGTH除以2:

DECLARE @str nvarchar(4000) , 
        @pat varchar(100) = '%[^ ' + CHAR(9) + '-' + CHAR(13) + ']%';

SET @str = /* load value */

SET @str = SUBSTRING( @str , PATINDEX( @pat , @str ) , 
        DATALENGTH( @str ) / 2 - 
        PATINDEX( @pat , @str ) - 
        PATINDEX( @pat , REVERSE( @str )) + 2 );

请注意,此处使用的模式(@pat)仅涵盖ASCII字符。这足以满足我的要求,但如果需要完整的Unicode支持,则可以扩展模式。有关完整列表,请参阅Wikipedia: Whitespace character

当然,将其转换为UDF以便于重复使用会相当容易。

答案 2 :(得分:0)

你应该试试这个:

DECLARE @testString varchar(255)
set @testString = 'MY STRING      '

/*I always use this like a final solution*/
SET @testString = REPLACE(REPLACE(REPLACE(@testString, CHAR(9), ''), CHAR(10), ''), CHAR(13), '')
 SELECT @testString   

/*
CHAR(9)       - Tab
CHAR(10) - New Line
CHAR(13) - Carriage Return
*/

答案 3 :(得分:0)

使用以下查询,这有效:

    DECLARE @trimchars VARCHAR(10),@str varchar(max)  
SET @trimchars = CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32)  
set @str='test string            it is'
IF @str LIKE '[' + @trimchars + ']%' SET @str = SUBSTRING(@str, PATINDEX('%[^' + @trimchars + ']%', @str), 8000)  
IF @str LIKE '%[' + @trimchars + ']' SET @str = SUBSTRING(reverse(@str), PATINDEX('%[^' + @trimchars + ']%', reverse(@str)), 8000)  
select @str

答案 4 :(得分:0)

我发现了这个here,并稍微改了一下。它适用于你的情况。任何建议或反馈都将非常感激。

Go

CREATE FUNCTION dbo.LeftTrim(@str VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @trimchars VARCHAR(10)

    SET @trimchars = CHAR(9) + CHAR(10) + CHAR(13) + CHAR(32)

    IF @str LIKE '[' + @trimchars + ']%'
        SET @str = STUFF(@str, 1, PATINDEX('%[^' + @trimchars + ']%', @str) - 1, '')

    RETURN @str
END
GO


CREATE FUNCTION dbo.RightTrim(@str VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @trimchars VARCHAR(10)

    SET @trimchars = CHAR(9) + CHAR(10) + CHAR(13) + CHAR(32)

    IF @str LIKE '%[' + @trimchars + ']'
        SET @str = REVERSE(dbo.LeftTrim(REVERSE(@str)))

    RETURN @str
END
GO

CREATE FUNCTION dbo.SuperTrim(@str VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
    RETURN dbo.LeftTrim(dbo.RightTrim(@str))
END
GO

- 插图

DECLARE @testStr AS VARCHAR(MAX)=''
SELECT @testStr='my first line ' + CHAR(13) + CHAR(10)  + CHAR(13) + CHAR(10)  + CHAR(13) + CHAR(10)  + 'second line ' + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10)

SELECT dbo.SuperTrim(@testStr) + '--end of line' 

答案 5 :(得分:0)

检查并尝试以下脚本(已通过单元测试)-

--Declaring Table Variable
DECLARE @Tbl TABLE(col_1 VARCHAR(100));

--Test Samples
INSERT INTO @Tbl (col_1)
VALUES
('  EY     y            
Salem')
, ('  EY     P    ort       Chennai   ')
, ('  EY     Old           Park   ')
, ('  EY   ')
, ('  EY   ')
,(''),(null),('d                           
    f');

SELECT col_1 AS INPUT,
    LTRIM(RTRIM(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
        REPLACE(
        REPLACE(
        REPLACE(
        REPLACE(
        REPLACE(
        REPLACE(col_1,CHAR(10),' ')
        ,CHAR(11),' ')
        ,CHAR(12),' ')
        ,CHAR(13),' ')
        ,CHAR(14),' ')
        ,CHAR(160),' ')
        ,CHAR(13)+CHAR(10),' ')
    ,CHAR(9),' ')
    ,' ',CHAR(17)+CHAR(18))
    ,CHAR(18)+CHAR(17),'')
    ,CHAR(17)+CHAR(18),' ')
    )) AS [OUTPUT]
FROM @Tbl;