3

请注意,我想在字符串中找到我指定的特殊字符。

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”。那么什么是右括号的正确匹配。

4

1 回答 1

3

根据这个链接,看起来[[不是逃避[而是[[]。换句话说,左右方括号对的左方括号。

既然如此,你的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)。我试着像逃避它一样--,虽然这有效,但我的附加测试用例 a+被破坏了。我觉得这很奇怪,但最后决定-用另一个我知道我会拒绝的字符替换可能会更容易(.)。
  • 字符串REPLACE函数通过从表达式中完全删除有问题的特殊字符来降低PATINDEX(并使其实际工作)的复杂性。假设您在 中始终至少有一个要拒绝的字符PATINDEX,则使用这些REPLACE表达式应该是一种可行的解决方案。从理论上讲,它会使事情变慢一点,但这只是需要在现实生活中进行测试,看看它是否重要。

我知道这个解决方案有效,因为我已经能够对其进行测试。只需要一点时间就可以启动并运行 SQL Server Express Edition!

于 2012-12-17T14:54:29.297 回答