2014-09-28 117 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'