2017-02-12 3 views
0

Dies sollte eine einfache sein, obwohl ich nicht ganz eine geeignete Lösung gefunden.SQL-Server ersetzen Teile einer Zeichenfolge mit Regex

Ich muss eine (eher) einfache Ersetzung mit SQL (SQL Server) wie folgt implementieren. Stellen Sie sich eine Zeichenfolge, die wie folgt aussieht:

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

Mit anderen Worten, ein Muster [0004] sollte [4] werden.

ich machen zunächst dachte, die ersetzt wie:

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

aber, noch bevor es zu testen, wurde mir klar, dass es auch [0]-[] umwandeln würde, die nicht wollen, ist ich will.

Ich weiß, wie man es einfach in PL/SQL macht, aber in SQL Server habe ich Schwierigkeiten.

Jede Hilfe wird am meisten geschätzt.

+0

Dies ist ziemlich schmerzhaft in SQL Server zu tun. –

+0

Wenn Sie CLR-Assemblys verwenden dürfen, verfügt [SqlSharp] (http://www.sqlsharp.com/features/) über Implementierungen von RegEx sowie eine ganze Reihe hervorragender CLR-Funktionen. – SqlZim

+0

Vielen Dank @SqlZim, aber nein, ich kann diese Art von Dingen nicht verwenden (Firmenrichtlinie). Ich dachte daran, nach '[0', von dort'] 'zu suchen, und wenn es Ziffern dazwischen gibt, ersetze das erste' [0' mit '[' '. Dann Schleife, bis keine weiteren Fälle gefunden wurden. Das würde funktionieren, aber seine Hässlichkeit verursacht mir Schmerzen. – FDavidov

Antwort

2

Eine andere Option. Dies ersetzt bis zu 25 Vorkommen von "[0] und mehreren [...]" pro Zeile.

Beispiel

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 

Returns

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

Hinweis: Wenn eine Tabelle der Verarbeitung, wird es eine kleine Sache sein, einige XML

+0

Schön gemacht. Hinweis: Dies funktioniert auch mit der ** aktualisierten ** Testzeichenfolge: http://rextester.com/VPYA60373 Rückgabe 'Dies ist ein einfaches Beispiel, wo aaa [4] sollte aaa [4] und b [0], c [ 1] sollte unverändert bleiben. – SqlZim

+0

@SqlZim Danke, manchmal braucht man nur einen Hammer.Es ist nicht elegant, aber erledigt den Job :) –

+0

Sie müssen einige ausgefallene Hämmer haben! – SqlZim

1

Folgenden möchte anwenden arbeiten für bis zu 15 führende Nullen Wenn es ein Zeichen (~ unten) gibt, dass Sie einigermaßen sicher sein können, wird es nie in den Daten erscheinen.

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

Demo

+0

Vielen Dank Martin für Ihren Vorschlag Ich habe es als Samen genommen und eine andere Lösung ausgearbeitet, ohne die Anzahl der Nullen zu begrenzen sind interessiert. Prost! – FDavidov

+0

@FDavidov - Gibt es in der Praxis keine Beschränkung auf die Anzahl der 0s? Welche Art von Nummer ist das? 15 ist mehr als genug für eine 32-Bit-Int und Sie können die Anzahl der führenden Nullen bis 31 unterstützt durch Hinzufügen einer weiteren "REPLACE" mit 16 Nullen. Prozedurale Schleife sollte in SQL Server im Allgemeinen vermieden werden. –

+0

Martin, ich stimme völlig mit Ihnen in Bezug auf den tatsächlichen Bedarf für alles über 15 Nullen. In der Praxis erwarte ich nicht mehr als 1- 2 führende Nullen. Meine Herangehensweise (im Allgemeinen) betrifft Gerätemechanismen, die überhaupt keine Einschränkung haben (selbst wenn in der Praxis ein grenzenloser Zustand niemals eintreten würde), wenn die Lösung nicht ** teuer ist **. Ich stimme Ihnen bezüglich Ihres Vorschlags, Schleifen in SQL zu vermeiden, nicht zu. Sie sollten verwendet werden, wenn es richtig ist, sie zu verwenden und sie zu vermeiden, wenn dies nicht der Fall ist. SQL ist eine Programmiersprache wie jede andere auch und sollte intelligent wie jede andere verwendet werden. – FDavidov

0

Dank Martin Vorschlag arbeitete ich die folgende Lösung:

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

und das Ergebnis ist:

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

Nochmals vielen Dank an Martin !!!

Verwandte Themen