2012-12-17 39 views
3

請注意,我想找到字符串中的特殊字符,而不是我指定的字符。TSQL允許匹配右方括號也從字符串

DECLARE @Temp1 NVARCHAR(100) 
SET @Temp1 ='Rajesh[sdf]' 
SELECT PATINDEX('%[^0-9A-Za-z .&()[[,''-]%',@Temp1) 

經過漫長的調查結果我得到了允許左括號,我們不得不把兩次[即[ 但這不是右括號 表達PATINDEX('%[案件^ 0〜 9A-Za-z &()[[],'' - ]%',@Temp1)沒有給出預期的正確結果。

DECLARE @Temp1 NVARCHAR(100) 
SET @Temp1 ='Rajesh[sdf]' 
SELECT PATINDEX('%[^0-9a-z .&()[[],''-]%',@Temp1) 

上面的代碼返回patindex 0,因爲我已經刪除了大寫字母。它應該返回1匹配'R'。那麼什麼是右支架的正確匹配。

+2

「因爲我刪除了大寫字母,它應該返回1」。除了二進制排序之外,這是不正確的。在不區分大小寫的排序規則中,'a-z'也與大寫字母匹配。在區分大小寫的'a-z'匹配除'Z'之外的所有字母。 –

+0

此外,沒有必要雙左方括號。 'SELECT PATINDEX('[[]','[')'返回'1',如果你要在集合中包含'-',那麼它必須是第一個字符[用於可預測的結果](https:// connect .microsoft.com/SQLServer的/反饋/信息/ 742841 /圖案語法無證差式 - 行爲 - VARCHAR-VS-nvarchar的間)。不知道如何逃避']'雖然... –

+0

而你正在搜索的一些單個字符有連續的字符代碼,所以你可以做4個範圍匹配和只剩下一個寬鬆的字符'PATINDEX('[0 -9A-Z& - ), - 。[]',@Temp1 COLLATE Latin1_General_100_BIN)'不幸']'不在任何範圍內,所以仍然沒有處理。 –

回答

3

根據this link,看起來[[不是[的轉義,而是[[]。換句話說,左方括號內的是左右方括號對。

因此,您的PATINDEX應如下。

PATINDEX('%[^0-9A-Za-z .&()[[]],''-]%',@Temp1) 

通知由於第一]附加]關閉出[]一對匹配[

編輯#1:

如果你嘗試這樣的事情?我們正在做的是首先用()替換令人煩惱的[]字符,然後搜索不在列表中的特殊字符。

DECLARE @Temp1 NVARCHAR(100) 
SET @Temp1 ='Rajesh[sdf]' 
SET @Temp1 = REPLACE(@Temp1,'[','(') 
SET @Temp1 = REPLACE(@Temp1,']',')') 
SELECT PATINDEX('%[^0-9A-Za-z .&(),''-]%',@Temp1) 

不幸的是,目前我無法測試這個,因爲我沒有第二個SQL Server的工作副本。一旦我安裝了一個,我會盡量測試一下。

編輯#2:

現在,我已經能夠測試,我已經證實了這一點作爲一個可能的解決方案。

DECLARE @Temp1 NVARCHAR(100) 
SET @Temp1 ='Rajesh[sdf]+' 
SET @Temp1 = REPLACE(@Temp1,'[','.') 
SET @Temp1 = REPLACE(@Temp1,']','.') 
SET @Temp1 = REPLACE(@Temp1,'-','.') 
SELECT PATINDEX('%[^0-9a-z .&(),'']%',@Temp1 COLLATE Latin1_General_BIN) 

有幾個挑戰需要克服。

  • 我的數據庫代碼頁是不區分大小寫(SQL_Latin1_General_CP1_ CI _As)。我需要使用COLLATE來解決這個問題。請注意,我使用了BIN排序規則,因爲即使排序規則CS的行爲並不像預期的那樣。這解決了刪除A-Z仍然不符合R的問題。
  • -字符從原來的PATINDEX表達式無法正常工作。這可能是因爲它是表達式中的特殊字符(即a-z中的「through」)。我嘗試像--一樣逃脫它,雖然這工作,我的額外的+測試案例被打破。我發現這很奇怪,但最終決定用另一個我知道我會拒絕的角色(.)代替-可能會更容易。
  • 字符串REPLACE功能降低了PATINDEX的複雜性(並使得實際工作)通過從完全表達除去違規特殊字符。假設您至少會在PATINDEX中至少有一個字符被拒絕,使用這些REPLACE表達式應該是一個可行的解決方案。從理論上講,它會使事情減緩一些,但這些事情只能在現實生活中進行測試,看看它是否重要。

我知道,這個解決方案工程,我已經能夠測試它。只需要一點時間即可啓動並運行SQL Server Express Edition!

+0

爲SET結果@ TEMP1 = '拉傑什[SDF]' SELECT PATINDEX( '%[^ 0-9A-Z&()[[]],' ' - ]%',@ TEMP1)不匹配ř因爲我已經刪除了AZ。 –

+0

我想我很困惑。你想匹配'R'還是''''?如果你刪除了你的角色類('A-Z')的大寫字母,那麼它不應該匹配'R'。在這種情況下,它似乎按預期工作。它是否匹配']'? –

+0

現在我看到'^'...我明白你想要什麼了。對不起,我的誤解。我試圖重現這個問題,但沒有任何運氣。 –

相關問題