2

我正在尝试过滤用作 Outlook 邮件主题行的字符串。我使用过滤器 b/c 一些具有特殊字符的字符串会将主题行转换为我想要阻止的 Unicode。我正在尝试使用 PATINDEX,但无法将括号放入模式中,有没有人知道如何做到这一点和/或有一个好的网站可以分享为 PATINDEX 创建模式的指南。这是我所拥有的:

-- First replaces special characters with similar safe ones.
-- Finally excludes all other characters not specified in the pattern.
-- =============================================

ALTER Function [dbo].[RemoveSpecialCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
BEGIN
    DECLARE @KeepValues as varchar(50)

    SET @Temp = Replace(Replace(Replace(Replace(Replace(Replace(Replace(@Temp,'”','"'),'“','"'),'‘','`'),'’','`'),'–','-'),'[','('),']',')')
    SET @KeepValues = '%[^a-z0-9()."`:;,#&+*\/-]%'

    WHILE PatIndex(@KeepValues, @Temp) > 0
        SET @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')

    RETURN @Temp
END

正如你所看到的,因为我不知道如何在模式中获得括号,所以现在我用括号替换它们。

4

2 回答 2

0

-- 首先用类似的安全字符替换特殊字符。

看起来好像您想用常规引号替换打开引号,用常规引号替换关闭引号等......您可以使用一个技巧来做到这一点,而不必弄乱一堆替换。我不会假装知道所有关于排序规则的知识,但我确实知道它们可以做一些你意想不到的非常奇怪的事情,有时你可以利用它来发挥自己的优势。

例如:

Declare @Temp VarChar(100)
SET @Temp = '”“‘’–'
Select @Temp,
        @Temp Collate SQL_Latin1_General_Cp850_CI_AS

当你运行上面的代码时,你会看到数据类型是 varchar。我们用开引号、闭引号等设置字符串……如果不指定排序规则,sql 将使用默认的数据库排序规则返回数据。如果您确实指定了排序规则,SQL 将使用排序规则返回数据。

如您所见,您想用“安全”特殊字符替换的所有特殊字符实际上都被替换了。

把这一切放在一起:

Alter Function [dbo].[RemoveSpecialCharacters](@Temp VarChar(1000))
Returns VarChar(1000) 
AS
BEGIN
    DECLARE @KeepValues as varchar(50)

    SET @Temp = @Temp Collate SQL_Latin1_General_Cp850_CI_AS
    SET @KeepValues = '%[^a-z0-9()."`'':;,#&+*\/-[[][]]]%'

    WHILE PatIndex(@KeepValues, @Temp) > 0
        SET @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')

    RETURN @Temp Collate Database_Default
END

请注意,在函数内部,数据被转换为不同的排序规则,返回值将其转换回数据库的默认排序规则。

我还将左方括号和右方括号放入 KeepValues。

使用替换功能不一定是坏事,但是转换排序规则会执行得更快,并且会产生相同的结果。标量函数作为性能杀手而臭名昭著,因此尽可能快地使它们符合您的最大利益(并且您应该对这个函数的性能感到满意)。

现在......我之前说过,我不知道所有关于排序规则的知识,所以可能会有一些意外。大多数字符将是相同的,但有一些区别:

€    ?
    ?
‚    '
ƒ    ƒ
„    "
…    .
†    ┼
‡    ╬
ˆ    ^
‰    %
Š    S
‹    <
Π   O
    ?
Ž    Z
    ?
    ?
‘    '
’    '
“    "
”    "
•    
–    -
—    -
˜    ~
™    T
š    s
›    >
œ    o
    ?
ž    z
Ÿ    Y

使用上面显示的数据,您可以将其解释为:当您转换排序规则时,第一个字符将替换为第二个字符,如我在上面的代码中所示。

于 2014-03-07T16:28:36.937 回答
0
SET @KeepValues = '%[^a-z0-9()."`:;,#&+*\/-[]][[]]%'

左括号 = [[] 右括号 = []]

编辑:

下面完全避免了 PATINDEX 来完成同样的事情。请让我知道这对你有没有用。

DECLARE @input VARCHAR(1000) = 'th,is i[s @a] [[.[ te[  st '
        , @Temp VARCHAR(1000) = ''
        , @index INT = 1
        , @char CHAR(1);

WHILE @index <= LEN(@input)
BEGIN
    SET @char = SUBSTRING(@input, @index, 1);
    IF @char LIKE '[a-z0-9()."`:;,#&+*\/-]' OR @char = '[' OR @char = ']'
        SET @temp += @char;
    SET @index += 1;
END;
PRINT @Temp;
于 2014-03-07T14:30:55.843 回答