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),那么什么都不应该被替换。

我尝试了REPLACEPATINDEX 函数的一些组合,但我无法实现。

【问题讨论】:

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 替换函数中的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

sql server中对字段使用正则表达式替换???

替换 PL/SQL 中的几行正则表达式函数

sql server 查找与替换 正则表达式 匹配

带正则表达式的参数化 SQL、ORACLE 与 SQL Server

SQL SERVER 正则替换

SQL 注释中的 Java 正则表达式查找/替换模式