获取字符串分隔符内部的子字符串SQL Server 2012

时间:2019-01-07 22:21:46

标签: sql-server substring

如何提取右侧[..]内的子字符串 字符串全名的内容?

示例。

'asdfasfasfs Full Name [Lorem,Ipsum] asdfds Client Name [adfore, fipsum] asdfas'

然后我想要字符串

  

Lorem,Ipsum

输出。

我尝试过

SELECT DECLARE @Parameter VARCHAR(100)
SET @Parameter= 'asdfasfasfs Full Name [Lorem,Ipsum] asdfds Client Name [adfore, fipsum] asdfas'

SELECT  SUBSTRING(@Parameter, CHARINDEX(' Full Name [', X))

但是我不知道如何到达[全名之后 并且由于[...]中的字符串长度可变,所以我不知道如何到达该位置 结束]。

3 个答案:

答案 0 :(得分:2)

使用找到的第一个[的CharIndex作为起点:

SELECT SUBSTRING(@s, 
                 CHARINDEX('[', @s, CHARINDEX('Full Name', @s, 1)) + 1, 
                 CHARINDEX(']', @s, CHARINDEX('[', @s, CHARINDEX('Full Name', @s, 1))) 
                 - CHARINDEX('[', @s, CHARINDEX('Full Name', @s, 1)) - 1) 

CHARINDEX(']', @s, CHARINDEX('[', @s, CHARINDEX('Full Name', @s, 1)))-是]之后的第一个[之后的第一个Full Name的字符索引。

从中减去找到的第一个[的位置,以确定子字符串的长度。

起始位置的+ 1是为了避免[,长度上的- 1是为了避免]

编辑-进一步说明:

DECLARE @s NVARCHAR(255) = N'asdfasfasfs Full Name [Lorem,Ipsum] asdfds Client Name [adfore, fipsum] asdfas'

我需要的第一条信息是代表所关注数据的“标签”的位置。您希望在“全名”之后输入数据,因此我在字符串中查找了“全名”的位置。

DECLARE @label NVARCHAR(100) = N'Full Name'
DECLARE @labelPos INT = CHARINDEX('Full Name', @s, 1)

一旦有了标签的位置,就必须找到标签后面的第一个开/关括号的位置。

DECLARE @openBracketPos INT = CHARINDEX('[', @s, @labelPos)
DECLARE @closeBracketPos INT = CHARINDEX(']', @s, @openBracketPos)

有了这些位置,我现在可以确定括号内数据的长度。由于包括一个方括号在内的差异,有必要减去一个额外的字符。

DECLARE @fieldLength INT = @closeBracketPos - @openBracketPos - 1

一旦我掌握了所有这些信息,就只需要构造一个SUBSTRING调用来提取字符串的那部分即可。 +1指示SUBSTRING从跟在方括号后面的字符开始。

SELECT SUBSTRING(@s, @openBracketPos + 1, @fieldLength)

为了避免额外的步骤和可变的用法,我将以上所有内容简单地组合为一个语句。希望这会有所帮助!

答案 1 :(得分:1)

如果对TVF开放...

作为TVF,很容易将其包含在CROSS APPLY中

示例

DECLARE @Parameter VARCHAR(100)
SET @Parameter= 'asdfasfasfs Full Name [Lorem,Ipsum] asdfds Client Name [adfore, fipsum] asdfas'

Select * 
 From  [dbo].[tvf-Str-Extract](@Parameter,'[',']')

返回

RetSeq  RetPos  RetVal
1       24      Lorem,Ipsum
2       57      adfore, fipsum

感兴趣的功能

CREATE FUNCTION [dbo].[tvf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table 
As
Return (  

with   cte1(N)   as (Select 1 From (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
       cte2(N)   as (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
       cte3(N)   as (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
       cte4(N,L) as (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)

Select RetSeq = Row_Number() over (Order By N)
      ,RetPos = N
      ,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1) 
 From  ( Select *,RetVal = Substring(@String, N, L) From cte4 ) A
 Where charindex(@Delimiter2,RetVal)>1
)
/*
Max Length of String 1MM characters

Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[tvf-Str-Extract] (@String,'[[',']]')
*/

答案 2 :(得分:1)

  

然后我要输出字符串Lorem, Ipsum

使用CHARINDEX()作为

DECLARE @Parameter VARCHAR(100)
SET @Parameter= 'asdfasfasfs Full Name [Lorem,Ipsum] asdfds Client Name [adfore, fipsum] asdfas'

SELECT SUBSTRING(@Parameter,
                 CHARINDEX('[', @Parameter)+1, 
                 CHARINDEX(']', @Parameter)-CHARINDEX('[', @Parameter)-1)