在 SQL 服务器中,删除两个字符串之间的所有内容

In SQL Server, remove everything between two strings

在 SQL Server 2008 中,我有一个 table 列,其中包含不同方式的引用文本。我试图在 select 期间找到一种方法来删除这些引号并仅保留原始文本。

这是一个sqlfiddle

CREATE TABLE ExampleTexts
    ([text] varchar(max))
;

INSERT INTO ExampleTexts
    ([text])
VALUES
    ('[q]This is a quote[/q]Platform for building enterprise provisioning solutions'),
    ('[q attribute]This is a quote with an attribute [/q]Full-featured access management'),
    ('[q]This is a quote[/q]Robust LDAP server [q]This is another quote[/q] for Java'),
    ('[q]This is a quote [q]This is another quote[/q][/q]Robust LDAP server for Java'),
    ('This is a text, but guess, without a quote'),
    ('Maybe we have this [q] but without the ending tag')
;

如您所见,引号始终以 [q 开头并始终以 [/q] 结尾。我可以在一个字段中引用一个或多个引号。带有 [q attribute] 等属性的引号、嵌套引号,甚至带有起始标记但没有结束标记的误报。

上面的期望输出是

|                                                                               text |
|------------------------------------------------------------------------------------|
|                            Platform for building enterprise provisioning solutions |
|                                                    Full-featured access management |
|                                                        Robust LDAP server for Java |
|                                                        Robust LDAP server for Java |
|                                         This is a text, but guess, without a quote |
|                                  Maybe we have this [q] but without the ending tag |

我尝试了以下解决方案,但它们都不能处理所有情况

SELECT case when charindex('q]',text) > 0 then right (text, (len(text)- charindex('q]',text) - 1)) else text end FROM ExampleTexts

SELECT Replace(Replace(text, '[q', ''), '/q]', '') FROM ExampleTexts

试试这个功能:

CREATE FUNCTION dbo.ClearQuotes (
    @text varchar(MAX)
)
RETURNS varchar(MAX)
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN

    DECLARE
        @o_tag varchar(2) = '[q',
        @c_tag varchar(4) = '[/q]'

    DECLARE
        @o int = CHARINDEX( @o_tag, @text ),
        @c int = CHARINDEX( @c_tag, @text ),
        @b bit = 0,
        @x varchar(MAX);

    WHILE @o > 0 AND @c > 0 BEGIN

        -- Get the quoted segment.
        SET @x = SUBSTRING ( @text, @o, @c - @o + LEN ( @c_tag ) );

        -- Set the nested-quote bit flag to false.
        SET @b = 0;

        -- Look for a nested quote.
        IF CHARINDEX ( @o_tag, @x, LEN ( @o_tag ) ) > 0
            SET @b = 1;

        WHILE @b = 1 BEGIN

            -- Get the next open tag position.
            SET @o = CHARINDEX ( @o_tag, @text, @o + LEN ( @o_tag ) );
            SET @x = SUBSTRING ( @text, @o, @c - @o + LEN ( @c_tag ) );

            IF CHARINDEX ( @o_tag, @x, LEN ( @o_tag ) ) = 0
                SET @b = 0;

        END

        -- Remove the unwanted quote.
        SET @text = STUFF ( @text, @o, @c - @o + LEN ( @c_tag ), '' );

        -- Check again.
        SELECT
            @o = CHARINDEX( @o_tag, @text ),
            @c = CHARINDEX( @c_tag, @text );

    END

    RETURN LTRIM ( RTRIM ( @text ) );

END
GO

以下是针对您的示例数据集的结果:

DECLARE @ExampleTexts table ( [text] varchar(MAX) );
INSERT INTO @ExampleTexts VALUES
    ('[q]This is a quote[/q]Platform for building enterprise provisioning solutions')
    , ('[q attribute]This is a quote with an attribute [/q]Full-featured access management')
    , ('[q]This is a quote[/q]Robust LDAP server [q]This is another quote[/q] for Java')
    , ('[q]This is a quote [q]This is another quote[/q][/q]Robust LDAP server for Java')
    , ('This is a text, but guess, without a quote')
    , ('Maybe we have this [q] but without the ending tag');

SELECT
    dbo.ClearQuotes ( [text] ) AS cleaned_text
FROM @ExampleTexts;

Returns

+---------------------------------------------------------+
|                      cleaned_text                       |
+---------------------------------------------------------+
| Platform for building enterprise provisioning solutions |
| Full-featured access management                         |
| Robust LDAP server  for Java                            |
| Robust LDAP server for Java                             |
| This is a text, but guess, without a quote              |
| Maybe we have this [q] but without the ending tag       |
+---------------------------------------------------------+