2017-02-12 109 views
0

这应该是一个简单的,虽然我没有找到合适的解决方案。SQL-Server使用正则表达式替换部分字符串

我需要实现一个(相当)简单的替换使用SQL(SQL Server),如下所示。想象一下,你有一个字符串,它看起来像:

'This is a simple example where aaa[0004] should become aaa[4] and b[0],c[1] should remain unchanged' 

换句话说,模式[0004]应该成为[4]

我最初以为做的替换这样的:即使测试之前

SET @MyString = REPLACE(@MyString,'[0','[') ; 

但是,我意识到,这也将转换[0][],这不是要我要。

我知道如何在PL/SQL中很简单地做到这一点,但在SQL Server中我遇到了困难。

任何帮助将不胜感激。

+0

这在SQL Server中很痛苦。 –

+0

如果您可以使用CLR程序集,[SqlSharp](http://www.sqlsharp.com/features/)具有RegEx的实现以及大量优秀的CLR功能。 – SqlZim

+0

谢谢@SqlZim,但不,我不能使用这种类型的东西(公司政策)。我想过搜索'[0',从那里']',如果中间有数字,用'['替换第一个'[0'。然后循环,直到没有发现这种情况。那会奏效,但它的丑陋让我感到痛苦。 – FDavidov

回答

2

另一种选择。这将取代最多25次出现的'[0'和每行多个''。

Declare @MyString varchar(max) = 'This [0] [000] is a simple example where aaa[0004] should become aaa[4] and test [0]' 

Select @MyString = Replace(@MyString,MapFrom,MapTo) 
    From (
     Select MapFrom='0]',MapTo='§§0]' 
     Union All   
     Select Top 25 '[0','[' From master..spt_values 
     Union All 
     Select '§§0]','0]' 
     ) b 

Select @MyString 

返回

This [0] [0] is a simple example where aaa[4] should become aaa[4] and test [0] 

注:如果处理的表格,这将是一件小事应用一些XML

+0

做得很好。注意:这也适用于**更新**测试字符串:http://rextester.com/VPYA60373返回'这是一个简单的例子,其中aaa [4]应该成为aaa [4]和b [0],c [ 1]应该保持不变' – SqlZim

+0

@SqlZim谢谢,有时你只需要一把锤子。这不是优雅的,但完成了工作:) –

+0

你必须有一些奇特的锤子! – SqlZim

1

下将工作多达15个前导零如果有一个字符(下面的~),那么您可以合理地确信永远不会出现在数据中。

SELECT 
REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
    REPLACE(
     REPLACE(X,'0]', '~'), 
    '[00000000','['), 
    '[0000','['), 
    '[00','['), 
    '[0','['), 
'~','0]') 
FROM YourTable 

Demo

+0

感谢Martin的建议,我把它作为种子,制定了另一个解决方案,没有限制0的数量。有兴趣,干杯! – FDavidov

+0

@FDavidov - 实际上对0的数量没有限制吗?这是什么类型的数字?15对于32位整数绰绰有余,你可以增加支持的前导零树的数量为31通过添加另一个具有16个零的REPLACE,程序循环通常应该在SQL Server中避免 –

+0

Martin,我完全同意你关于超过15个零的任何事情的实际需求,实际上, 2前导零。我的方法(一般来说)是设备机制,如果解决方案不是**代价高昂的,那么它根本就没有限制(即使在实践中永远不会发生无限的情况)。我不同意你关于避免SQL内循环的建议。他们应该在**正确时使用**使用它们,当它们不使用时应避免使用它们。 SQL是一种编程语言,与任何其他语言一样,它应该被巧妙地使用。 – FDavidov

0

感谢Martin的建议下,我工作了以下解决方案:

Declare @MyString varchar(max) ; 
    Declare @MyString_T varchar(max) ; 

    SET @MyString = 'This is a simple example where aaa[00000000000000000000000000004] should become aaa[40] and test [000] and ccc[]' ; 

    WHILE (1=1) 
     BEGIN 
      SET @MyString_T = REPLACE(
           REPLACE(
            REPLACE(@MyString,'0]', '~'), 
           '[0','['), 
           '~','0]') ; 

      IF @MyString_T = @MyString 
       BREAK ; 
      ELSE 
       SET @MyString = @MyString_T ; 
     END ; 

    Print(@MyString) ; 

,其结果是:再次

This is a simple example where aaa[4] should become aaa[40] and test [0] and ccc[] 

感谢Martin!