【问题标题】:Get Substring Inside String Delimiter SQL Server 2012获取字符串分隔符内的子字符串 SQL Server 2012
【发布时间】:2026-02-20 17:40:01
【问题描述】:

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

示例。

'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))

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

【问题讨论】:

  • [adfore, fipsum] 怎么样?
  • @Sami 不。我只想要全名之后的内容。
  • 对我的问题投了反对票的人愿意解释原因吗?

标签: sql-server substring


【解决方案1】:

使用找到的第一个 [ 的 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)

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

【讨论】:

  • 谢谢!这需要我几个小时才能弄清楚。很遗憾 SQL Server 需要花这么多时间来操作字符串。介意您分享解决方案背后的思考过程吗?
【解决方案2】:

如果对 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,'[[',']]')
*/

【讨论】:

  • 在返回[] 中的选定值时为要查找的关键字提供第四个参数将是一个有趣的练习。例如[dbo].[tvf-Str-Extract](@String, '[', '[', 'Full Name') 将在 Full Name 之后返回 [...] 值。
  • @Forty3 你可以有一个更有针对性的提取 [dbo].[tvf-Str-Extract](@Parameter,'Full Name [',']')
  • 啊——聪明。谢谢!
【解决方案3】:

然后我想要字符串Lorem, Ipsumoutputted。

使用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)

【讨论】:

  • 这适用于[...] 值的第一个实例,但如果OP 想要[...] 值跟在Client Name 之后,则不行。
  • @Forty3 我知道,我在他的 Q 下留言,他没有回应,所以我按他说的回答。仅此而已。
  • 好点 - 我推断需要能够指定替代前体值以在字符串中进行搜索。诚然,该要求并未明确说明。