在大括号之间提取可变长度字符串

时间:2015-12-07 16:27:11

标签: sql-server regex tsql

这是列中某些字符串的基本结构:

SELECT  * 
FROM    #M
WHERE   ST LIKE '%(PRODUCED%)%'

我需要做的是在找到它时提取这个`(生成的%)。

我可以很容易地找到包含违规代码段(生成的%)'的行的出现:

(produced

我现在需要做的是删除从)到下一个大括号'please help me world X' 'please help me world Y' 'please help me world Z' 'please help me world K (produced' 的部分 - 您可以看到这两个短语之间的距离是可变的。

查询后,我希望得到以下结果:

CREATE TABLE #M(ST VARCHAR(250));
INSERT INTO #M
values
    ('please help me world  (produced... but needs to go) bb cc dd'),
    ('please help me world Y (produced_this is extra extra extra long)'),
    ('please help me world Z (producedthis isshort)'.xlsm),
    ('please help me world K (produced');

因为在第4个语句中没有右括号,所以保留原样。

编辑

在有问题的短语的右边可能有文字 - 所以一些字符串的更好例子如下:

{{1}}

1 个答案:

答案 0 :(得分:2)

您可以使用CHARINDEX确定字符串中显示'(produced'的位置,然后只提取左侧的字符(使用LEFT)。最后,你需要在case表达式中使用它,只在有右括号的地方应用逻辑:

SELECT  NewST = CASE WHEN ST LIKE '%(PRODUCED%)%' 
                        THEN LEFT(ST, CHARINDEX('(PRODUCED', ST) - 1)
                    ELSE ST 
                END
FROM    #M;

这给出了:

NewST
------------------------------
please help me world  
please help me world Y 
please help me world Z 
please help me world K (produced

这似乎是所需的输出。

修改

我猜')'并不总是成为字符串的最后一部分,在这种情况下你需要通过使用CHARINDEX的可选第三个参数来识别它,这是起始位置。基础是:

SELECT  *,
        CloseParenthesis = CHARINDEX(')', ST, OpenParenthesis)
FROM    (   SELECT  ST,
                    OpenParenthesis = CHARINDEX('(PRODUCED', ST)
            FROM    #M
        ) AS t;

给出了:

ST                                                                  OpenParenthesis     CloseParenthesis
----------------------------------------------------------------------------------------------------------
please help me world  (produced... but needs to go)                 23                  51
please help me world Y (produced_this is extra extra extra long)    24                  64
please help me world Z (producedthis isshort)                       24                  45
please help me world K (produced                                    24                  0

然后将这些值用于STUFF函数内括号的位置,以删除括号之间的所有内容:

SELECT  ST,
        NewST = CASE WHEN ST NOT LIKE '%(PRODUCED%)%' THEN ST
                    ELSE STUFF(ST, OpenParenthesis, CloseParenthesis - OpenParenthesis, '')
                END
FROM    (   SELECT  ST,
                    OpenParenthesis = CHARINDEX('(PRODUCED', ST) - 1,
                    CloseParenthesis = CHARINDEX(')', ST, CHARINDEX('(PRODUCED', ST)) + 1
            FROM    #M
        ) AS t;