2014-09-28 125 views
3

我需要修剪影响内部空白的字符串而不是的空格(包括制表符,换行符等)。例如:在不影响内部空白的情况下修剪空白



foo 
bar 
    baz 
    

将成为

foo 
bar 
    baz

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

回答

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个字节,则需要通过2在这种情况下,划分DATALENGTH:只有

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以便于重复使用相当容易。

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 
*/ 
+0

这是行不通的。正如我在问题中提到的,我需要保留内部空格,但是'REPLACE'将删除字符串中任何位置的指定字符。 – 2014-09-29 05:00:22

+0

我们只替换CHAR(9)CHAR(10)和CHAR(13)与空白。 – Navneet 2014-09-29 05:12:45

+0

我明白,但问题是,它应该只在字符串的开头或结尾出现这些字符。当他们出现在字符串的中间时,我需要保留它们。如果不清楚,请参阅上面的示例。 – 2014-09-29 05:21:23

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

我正在处理的脚本是维护过程的一部分。我需要完全独立的东西,不会依赖任何其他预先存在的对象。不过,我可以看到图书馆可以派上用场。我最终可能会反思我的脚本以利用其他一些功能。 +1因为这可能对未来的读者有用。 – 2014-09-29 18:47:57

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 
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'