Verwenden von RegEx in SQL Server


92

Ich suche nach Möglichkeiten zum Ersetzen / Codieren von Text mithilfe von RegEx basierend auf den folgenden RegEx-Einstellungen / -Parametern:

RegEx.IgnoreCase = True     
RegEx.Global = True     
RegEx.Pattern = "[^a-z\d\s.]+"   

Ich habe einige Beispiele für RegEx gesehen, war jedoch verwirrt darüber, wie es in SQL Server auf die gleiche Weise angewendet werden soll. Anregungen wären hilfreich. Danke dir.


1
Hallo, werfen Sie einen Blick auf diesen Artikel: codeproject.com/Articles/42764/…
Mohsen

Es gibt auch eine gute TSQL + Windows-API- Lösung bei Robyn Page und Phil Factor, die auf der VBScript.RegExp- Klasse basiert, die, wie ich glaube, seit Windows 2000 auf jeder Windows-Version ausgeliefert wird.
Julio Nobre

Wenn Sie RegEx über TSQL unbedingt benötigen, können Sie für SQL Server 2016 und höher R-Services verwenden .
Dave Mason

Antworten:


101

Sie müssen nicht mit verwaltetem Code interagieren, da Sie LIKE verwenden können :

CREATE TABLE #Sample(Field varchar(50), Result varchar(50))
GO
INSERT INTO #Sample (Field, Result) VALUES ('ABC123 ', 'Do not match')
INSERT INTO #Sample (Field, Result) VALUES ('ABC123.', 'Do not match')
INSERT INTO #Sample (Field, Result) VALUES ('ABC123&', 'Match')
SELECT * FROM #Sample WHERE Field LIKE '%[^a-z0-9 .]%'
GO
DROP TABLE #Sample

Wenn dein Ausdruck mit endet, +kannst du mitgehen'%[^a-z0-9 .][^a-z0-9 .]%'

BEARBEITEN : um es klar zu machen: SQL Server unterstützt keine regulären Ausdrücke ohne verwalteten Code. Abhängig von der Situation kann der LIKEOperator eine Option sein, es fehlt jedoch die Flexibilität, die reguläre Ausdrücke bieten.


8
@ MikeYoung, du hast recht. Diese Antwort adressiert den +Quantifizierer fälschlicherweise so, wie {1,2}er angenommen werden sollte {1, }. Überraschenderweise funktionierte dies für das OP.
Rubens Farias

2
Dies funktioniert in SQL Server nicht, da Regex nicht unterstützt wird.
VVN

10
@VVN LIKEist kein regulärer Ausdruck (es handelt sich um eine eingeschränktere Syntax für die Mustererkennung). Der Mangel an regulärer Unterstützung bedeutet also nicht, dass dies nicht funktioniert.
Charles Duffy

@RubensFarias Wäre es nicht schön, die Antwort angesichts der Kommentare von @ mike-young zu aktualisieren?
Sudhanshu Mishra

8

Leicht modifizierte Version von Julios Antwort.

-- MS SQL using VBScript Regex
-- select dbo.RegexReplace('aa bb cc','($1) ($2) ($3)','([^\s]*)\s*([^\s]*)\s*([^\s]*)')
-- $$ dollar sign, $1 - $9 back references, $& whole match

CREATE FUNCTION [dbo].[RegexReplace]
(   -- these match exactly the parameters of RegExp
    @searchstring varchar(4000),
    @replacestring varchar(4000),
    @pattern varchar(4000)
)
RETURNS varchar(4000)
AS
BEGIN
    declare @objRegexExp int, 
        @objErrorObj int,
        @strErrorMessage varchar(255),
        @res int,
        @result varchar(4000)

    if( @searchstring is null or len(ltrim(rtrim(@searchstring))) = 0) return null
    set @result=''
    exec @res=sp_OACreate 'VBScript.RegExp', @objRegexExp out
    if( @res <> 0) return '..VBScript did not initialize'
    exec @res=sp_OASetProperty @objRegexExp, 'Pattern', @pattern
    if( @res <> 0) return '..Pattern property set failed'
    exec @res=sp_OASetProperty @objRegexExp, 'IgnoreCase', 0
    if( @res <> 0) return '..IgnoreCase option failed'
    exec @res=sp_OAMethod @objRegexExp, 'Replace', @result OUT,
         @searchstring, @replacestring
    if( @res <> 0) return '..Bad search string'
    exec @res=sp_OADestroy @objRegexExp
    return @result
END

Sie benötigen Ole-Automatisierungsprozeduren, die in SQL aktiviert sind:

exec sp_configure 'show advanced options',1; 
go
reconfigure; 
go
sp_configure 'Ole Automation Procedures', 1; 
go
reconfigure; 
go
sp_configure 'show advanced options',0; 
go
reconfigure;
go

2
Übrigens ist es viel schneller, das Regex-Objekt zu zerstören und neu zu erstellen, als es zwischenzuspeichern und wiederzuverwenden. Wir haben 10.000 Vergleiche mit deutlich höheren Zahlen durchgeführt, um das Objekt wiederzuverwenden.
Zachary Scott

8

Wie in diesem Artikel müssen Sie eine CLR-Prozedur erstellen, die Regex-Funktionen bietet dargestellt.

Ihre Beispielfunktion verwendet VB.NET:

Imports System
Imports System.Data.Sql
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlTypes
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Imports System.Collections 'the IEnumerable interface is here  


Namespace SimpleTalk.Phil.Factor
    Public Class RegularExpressionFunctions
        'RegExIsMatch function
        <SqlFunction(IsDeterministic:=True, IsPrecise:=True)> _
        Public Shared Function RegExIsMatch( _
                                            ByVal pattern As SqlString, _
                                            ByVal input As SqlString, _
                                            ByVal Options As SqlInt32) As SqlBoolean
            If (input.IsNull OrElse pattern.IsNull) Then
                Return SqlBoolean.False
            End If
            Dim RegExOption As New System.Text.RegularExpressions.RegExOptions
            RegExOption = Options
            Return RegEx.IsMatch(input.Value, pattern.Value, RegExOption)
        End Function
    End Class      ' 
End Namespace

... und wird in SQL Server mit dem folgenden SQL installiert (wobei durch '%' getrennte Variablen durch ihre tatsächlichen Entsprechungen ersetzt werden:

sp_configure 'clr enabled', 1
RECONFIGURE WITH OVERRIDE

IF EXISTS ( SELECT   1
            FROM     sys.objects
            WHERE    object_id = OBJECT_ID(N'dbo.RegExIsMatch') ) 
   DROP FUNCTION dbo.RegExIsMatch
go

IF EXISTS ( SELECT   1
            FROM     sys.assemblies asms
            WHERE    asms.name = N'RegExFunction ' ) 
   DROP ASSEMBLY [RegExFunction]

CREATE ASSEMBLY RegExFunction 
           FROM '%FILE%'
GO

CREATE FUNCTION RegExIsMatch
   (
    @Pattern NVARCHAR(4000),
    @Input NVARCHAR(MAX),
    @Options int
   )
RETURNS BIT
AS EXTERNAL NAME 
   RegExFunction.[SimpleTalk.Phil.Factor.RegularExpressionFunctions].RegExIsMatch
GO

--a few tests
---Is this card a valid credit card?
SELECT dbo.RegExIsMatch ('^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$','4241825283987487',1)
--is there a number in this string
SELECT dbo.RegExIsMatch( '\d','there is 1 thing I hate',1)
--Verifies number Returns 1
DECLARE @pattern VARCHAR(255)
SELECT @pattern ='[a-zA-Z0-9]\d{2}[a-zA-Z0-9](-\d{3}){2}[A-Za-z0-9]'
SELECT  dbo.RegExIsMatch (@pattern, '1298-673-4192',1),
        dbo.RegExIsMatch (@pattern,'A08Z-931-468A',1),
        dbo.RegExIsMatch (@pattern,'[A90-123-129X',1),
        dbo.RegExIsMatch (@pattern,'12345-KKA-1230',1),
        dbo.RegExIsMatch (@pattern,'0919-2893-1256',1)

Dies ist in Classic ASP, unterstützt es? Ich denke, CLR ist nur für .NET-Funktionen, oder?
Control Freak

4
CLR-Prozeduren werden in der SQL Server-Umgebung installiert und können wie jede andere gespeicherte Prozedur oder benutzerdefinierte Funktion aufgerufen werden. Wenn Classic ASP also eine gespeicherte Prozedur oder eine benutzerdefinierte Funktion aufrufen kann, kann eine CLR-Prozedur aufgerufen werden.
Mwigdahl

1
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - Von der Überprüfung
Federico klez Culloca

Danke @FedericoklezCulloca. Dies war eine alte Antwort und ich habe sie entsprechend aktualisiert.
Mwigdahl

@mwigdahl danke dafür. Ich sehe, es ist alt, aber es tauchte in einer Bewertungswarteschlange auf :)
Federico klez Culloca

7

Reguläre Ausdrücke in SQL Server-Datenbanken Implementierung Verwendung

Regulärer Ausdruck - Beschreibung
. Übereinstimmen mit einem beliebigen Zeichen
* Übereinstimmen mit einem beliebigen Zeichen
+ Übereinstimmen mit mindestens einer Instanz des Ausdrucks vor
^ Beginn am Zeilenanfang
$ Suche am Zeilenende
< Nur übereinstimmen, wenn das Wort an diesem Punkt beginnt
> Nur übereinstimmen, wenn das Wort an diesem Punkt endet
\ n Zeilenumbruch abgleichen
[] Mit einem beliebigen Zeichen in Klammern übereinstimmen
[^ ...] Entspricht einem beliebigen Zeichen, das nicht nach ^
[ABQ]% aufgeführt ist. Die Zeichenfolge muss entweder mit den Buchstaben A, B oder Q beginnen und kann beliebig lang sein
[A B C D]% Die Zeichenfolge muss eine Länge von zwei oder mehr haben und mit A oder B beginnen und C oder D als zweites Zeichen
[AZ]% haben. Die Zeichenfolge kann beliebig lang sein und mit einem beliebigen Buchstaben von A bis Z
[A beginnen -Z0-9]% Die Zeichenfolge kann beliebig lang sein und muss mit einem beliebigen Buchstaben von A bis Z oder einer Ziffer von 0 bis 9 beginnen.
[^ AC]% Die Zeichenfolge kann beliebig lang sein, darf jedoch nicht mit den Buchstaben A bis C beginnen
% [AZ] Die Zeichenfolge kann beliebig lang sein und mit einem der Buchstaben von A bis Z enden.
% [% $ # @]% Die Zeichenfolge kann beliebig lang sein und muss mindestens eines der darin enthaltenen Sonderzeichen enthalten die Klammer


5
SELECT * from SOME_TABLE where NAME like '%[^A-Z]%'

Oder ein anderer Ausdruck anstelle von AZ


1

Ähnlich wie bei der Antwort von @ mwigdahl können Sie auch eine .NET-CLR in C # mit Code wie z.

using System.Data.SqlTypes;
using RX = System.Text.RegularExpressions;

public partial class UserDefinedFunctions
{
 [Microsoft.SqlServer.Server.SqlFunction]
 public static SqlString Regex(string input, string regex)
 {
  var match = RX.Regex.Match(input, regex).Groups[1].Value;
  return new SqlString (match);
 }
}

Installationsanweisungen finden Sie hier

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.