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.

Kontroll-Freak
quelle
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.

Rubens Farias
quelle
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
Zachary Scott
quelle
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)
mwigdahl
quelle
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

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

Oder ein anderer Ausdruck anstelle von AZ

Kalyan Vasanth
quelle
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

Fiach Reid
quelle