在 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 |
+---------------------------------------------------------+
在 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 |
+---------------------------------------------------------+