【问题标题】:String modification/filtering in MS SQL SERVER 2014MS SQL SERVER 2014 中的字符串修改/过滤
【发布时间】:2015-12-07 05:55:28
【问题描述】:

下面是输入字符串:

声明@inputvalue varchar(max)

Set @inputvalue = '球芽甘蓝 是一种绿色蔬菜,您应该毫无疑问地直接蒸掉。蒸你的只会增强你的免疫力。 生的球芽甘蓝球芽甘蓝仍然具有降低胆固醇的能力,但与蒸过的球芽甘蓝一样。同样,以下是蒸 brusselssprout 的其他一些健康益处。
我喜欢 sprout,而不是 布鲁塞尔

要求:

如果它们彼此不相邻,则需要删除词芽和布鲁塞尔,即

 1) 如果“Brussels”旁边不存在“Brussels”,则需要删除它(左或右,有或没有空格)
2) 如果“sprout”旁边不存在“sprout”,则需要删除单词“Brussels”(左或右,有或没有空格)
3) 即使单词之间有多个空格,也应将单词视为相邻。
Brussels           芽菜 - 不应将其从字符串中删除。
Brusselssprout            - 不应从字符串中删除。
      Sproutbrussels            - 不应从字符串中删除。

粗斜体高亮的字要去掉,粗体高亮的字不去掉。

注意:整个输入字符串可以不同/单词之间可能根本不包含空格。因此不能通过空格或任何其他分隔符分割来完成。

预期的输出字符串:

球芽甘蓝是一种绿色蔬菜,毫无疑问你应该直接蒸掉。蒸只会增强你的免疫力。生的球芽甘蓝或仍然具有降低胆固醇的能力,但与蒸球芽甘蓝一样。同样,以下是蒸球芽甘蓝的其他一些健康益处。 我喜欢,不是”

【问题讨论】:

  • 您可以编写一个使用 REGEX 的 CLR 脚本,如果您想精通它的话。否则用 PATINDEX 遍历字符串,分析两个目标词每次出现前后的字符。
  • CLR 脚本对我来说是不可能的,是的,迭代是我将选择的最后一个选项。
  • 只是对问题中的注释发表评论。拆分空格分隔符上的单词应该不是问题,因为您只查找单词brusselssprout,并删除旁边没有所需单词的单词。 BrusselssproutSproutburssels 是不同的词,不应该自然检查。

标签: sql sql-server sql-server-2008 tsql sql-server-2014


【解决方案1】:

这可能不是很有效,但它有效:

Declare @inputvalue varchar(max)

Set @inputvalue = 'Brussels sprout is one type of green veggie you should simply steam away without a doubt. Steaming your sprout will only enable a build up on your immunity. Raw Sproutbrussels or Brussels still has the cholesterol-lowering ability but as much as steamed brussels           sprout. Likewise, here are some of the other health benefits of steaming brusselssprout ".
I like sprout, not Brussels.';

declare @word1 nvarchar(100) = 'brussels';
declare @word2 nvarchar(100) = 'sprout ';

with W1(id, pos, val) as (
    Select 1, CHARINDEX(@word1, @inputvalue, 1)+1, 
        Case When
            right(rtrim(left(@inputvalue, CHARINDEX(@word1, @inputvalue, 1)-1)), len(@word2)) = @word2 
            or left(ltrim(right(@inputvalue, len(@inputvalue) - CHARINDEX(@word1, @inputvalue, 1) - len(@word1) +1)), len(@word2)) = @word2 
        then @inputvalue else 
            left(@inputvalue, CHARINDEX(@word1, @inputvalue, 1) - 1)
        end
    Union All
    Select id+1, CHARINDEX(@word1, val, pos)+1, 
        Case When
            right(rtrim(left(val, CHARINDEX(@word1, val, pos)-1)), len(@word2)) = @word2 
            or left(ltrim(right(val, len(val) - CHARINDEX(@word1, val, pos) - len(@word1) +1)), len(@word2)) = @word2 
        then val else 
            left(val, CHARINDEX(@word1, val, pos) - 1)
            + right(val, len(val) - len(@word1) - CHARINDEX(@word1, val, pos) + 1) 
        end
    From w1     
    Where CHARINDEX(@word1, val, pos) > 0
), W2(id, pos, val) as (
    Select 1, CHARINDEX(@word2, val, 1)+1, 
        Case When
            right(rtrim(left(val, CHARINDEX(@word2, val, 1)-1)), len(@word1)) = @word1 
            or left(ltrim(right(val, len(val) - CHARINDEX(@word2, val, 1) - len(@word2) +1)), len(@word1)) = @word1 
        then val else 
            left(val, CHARINDEX(@word2, val, 1) - 1)
        end
    From ( 
        Select val From w1 Where id in (Select max(id) From w1)
    ) as w
    Union All
    Select id+1, CHARINDEX(@word2, val, pos)+1, 
        Case When
            right(rtrim(left(val, CHARINDEX(@word2, val, pos)-1)), len(@word1)) = @word1 
            or left(ltrim(right(val, len(val) - CHARINDEX(@word2, val, pos) - len(@word2) +1)), len(@word1)) = @word1 
        then val else 
            left(val, CHARINDEX(@word2, val, pos) - 1)
            + right(val, len(val) - len(@word2) - CHARINDEX(@word2, val, pos) + 1) 
        end
    From w2 
    Where CHARINDEX(@word2, val, pos) > 0
)
Select val From w2 Where id in (Select max(id) From w2)

Option (maxrecursion 0)

CTE W1 也可以放在函数中:

with W1(id, pos, val) as (
    Select 1, CHARINDEX(@word1, @inputvalue, 1)+1, 
        Case When
            right(rtrim(left(@inputvalue, CHARINDEX(@word1, @inputvalue, 1)-1)), len(@word2)) = @word2 
            or left(ltrim(right(@inputvalue, len(@inputvalue) - CHARINDEX(@word1, @inputvalue, 1) - len(@word1) +1)), len(@word2)) = @word2 
        then @inputvalue else 
            left(@inputvalue, CHARINDEX(@word1, @inputvalue, 1) - 1)
        end
    Union All
    Select id+1, CHARINDEX(@word1, val, pos)+1, 
        Case When
            right(rtrim(left(val, CHARINDEX(@word1, val, pos)-1)), len(@word2)) = @word2 
            or left(ltrim(right(val, len(val) - CHARINDEX(@word1, val, pos) - len(@word1) +1)), len(@word2)) = @word2 
        then val else 
            left(val, CHARINDEX(@word1, val, pos) - 1)
            + right(val, len(val) - len(@word1) - CHARINDEX(@word1, val, pos) + 1) 
        end
    From w1     
    Where CHARINDEX(@word1, val, pos) > 0
)
Select val From w1 Where id in (Select max(id) From w1)

然后你只调用了两次:

Set @newvalue = replaceWords(replaceWords(@inputvalue, 'brussels', 'sprout'), 'sprout', 'brussels')

请注意,我喜欢球芽甘蓝!!! :)

【讨论】:

    猜你喜欢
    • 2021-07-02
    • 2016-03-27
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2020-03-21
    • 2020-03-30
    • 2016-08-17
    • 2016-09-15
    相关资源
    最近更新 更多