SQL Server 替换函数中的正则表达式
Posted
技术标签:
【中文标题】SQL Server 替换函数中的正则表达式【英文标题】:Regex in SQL Server Replace function 【发布时间】:2021-12-27 09:59:54 【问题描述】:假设我有一个带有随机文本的变量
DECLARE @sNumberFormat NVARCHAR(200) = 'randtext.here,999also-Random9He8re'
我想用[0-9]
替换999
中的每个9
。所以在这个例子中我想得到
'randtext.here,[0-9][0-9][0-9]also-Random9He8re'
问题是我永远不知道有多少个9
会放在括号中,所以可以有99
9999
..然后继续。我还需要验证是否有任何无效字符(不是9
),那么什么都不应该被替换。
我尝试了REPLACE
和PATINDEX
函数的一些组合,但我无法实现。
【问题讨论】:
SQL Server 不支持正则表达式,它的模式匹配能力充其量是初级的。 【参考方案1】:没有强大的正则表达式支持,SQL Server 的本机函数在这里没有提供太多帮助。一种有点hackish的方法是将输入字符串分成三个部分:
randtext.here,
999
also-Random9He8re
接下来,将中间目标子字符串中的 9
替换为 @
,或者您不希望出现在输入字符串中的其他任何位置的其他字符:
randtext.here,
@@@
also-Random9He8re
最后将中间子串中的@
替换为[0-9]
,然后拼接在一起得到最终结果:
DECLARE @val NVARCHAR(200) = 'randtext.here,999also-Random9He8re'
SELECT REPLACE(
SUBSTRING(@val, 1, CHARINDEX('9', @val) - 1) +
REPLACE(SUBSTRING(@val,
CHARINDEX('9', @val) + 1,
CHARINDEX('9', @val) - CHARINDEX('9', @val)), '9', '@') +
SUBSTRING(@val, CHARINDEX('9', @val) + 2, LEN(@val) - CHARINDEX('9', @val)),
'@', '[0-9]');
【讨论】:
【参考方案2】:所以我这个懒惰的开发者建议这样做:
SELECT Replace(
Replace(
Replace(
Replace(@input, '9999', '[0-9][0-9][0-9][0-9]')
, '999', '[0-9][0-9][0-9]')
, '99', '[0-9][0-9]')
, '9', '[0-9]') AS result
;
您可以继续扩展,只要您愿意执行(一次性?)替换。
快。简单的。可扩展。 Hacky。
有时懒惰是足够好的。
【讨论】:
【参考方案3】:这可以通过 CTE 系列来完成。它适用于方括号中任意数量的“9”值。
Declare @str varchar(max) = 'randtext.here,999also-Random9He8re';
With A As
(Select 1 As Pos
Union All
Select Pos+1 As Pos From A Where Pos < LEN(@str)
),
B As (
Select STRING_AGG(Case When Chr Like '[9]' Then Chr Else ' ' End, '') As Chr
From A Cross Apply (Select SUBSTRING(@str,A.Pos,1 )) As T(chr)
),
C As (
Select [value] As pattern,
REPLACE(REPLACE(REPLACE([value], '9', '[0-9]'),'',''),'','') As replacement,
ROW_NUMBER() Over (ORDER BY (SELECT NULL)) As Num,
COUNT(*) OVER (ORDER BY (SELECT NULL)) As Cnt
From B Cross Apply STRING_SPLIT(Chr,' ')
Where [value] Like '%' And [value] Like '%9%'
),
D As (
Select @str As Result, 1 As Num
Union All
select REPLACE(Result, C.pattern, C.replacement) As Res , D.Num+1 As Num
From D Inner Join C On (D.Num=C.Num)
Where D.Num<=C.Cnt)
Select Top 1 Result
From D
Order by Num Desc
A - 获取文本中的字符位置列表
B - 获取带有空格的文本,而不是其他字符
'9','',''
C- 获取模式和对应的替换值
D - 使用 REPLACEMENT 函数获取结果
【讨论】:
以上是关于SQL Server 替换函数中的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章