SQL ServerでのRegExの使用


92

以下のRegEx設定/パラメータに基づいて、RegExを使用してテキストを置換/エンコードする方法を探しています。

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

RegExの例をいくつか見ましたが、SQL Serverで同じようにそれを適用する方法について混乱しています。どんな提案も参考になります。ありがとうございました。


1
こんにちはこの記事をご覧
Mohsen

罰金もありますTSQL +のWindows APIで溶液ロビンページとフィルファクターのに依存しているVBScript.RegExpの私はbelieave、Windowsの2000年以来、すべてのWindowsのバージョンに出荷され、クラス、
フリオNobre

TSQLを介してRegExが確実に必要な場合、SQL Server 2016以降のオプションはRサービス使用することです。
Dave Mason

回答:


102

LIKEを使用できるため、マネージコードを操作する必要はありません。

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

あなたの表現が終わると、+あなたは一緒に行くことができます'%[^a-z0-9 .][^a-z0-9 .]%'

編集:明確にするために:SQL Serverは、マネージコードのない正規表現をサポートしていません。状況によっては、LIKE演算子がオプションになることもありますが、正規表現が提供する柔軟性に欠けています。


8
@MikeYoung、あなたは正しい。この答えは、+数量詞をと{1,2}解釈する必要がある場合と誤って扱います{1, }。驚いたことに、これはOPに有効でした。
ルーベンスファリアス2015

2
これは、正規表現をサポートしていないため、SQLサーバーでは機能しません。
VVN 2016年

10
@VVN LIKEは正規表現ではないため(より限定的なパターンマッチング構文です)、正規表現のサポートがないからといって、これが機能しないというわけではありません。
Charles Duffy

@RubensFariasは、@ mike-youngからのコメントを踏まえて回答を更新するのは良いことではないでしょうか?
Sudhanshu Mishra 2017

8

フリオの回答のわずかに変更されたバージョン

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

SQLでOleオートメーションプロシージャをオンにする必要があります。

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
ところで、正規表現オブジェクトを破棄して再作成する方が、キャッシュして再利用するよりもはるかに高速です。10,000の比較を実行し、オブジェクトを再利用して非常に高い数値を取得しました。
ザカリースコット

8

この記事で説明されているように、正規表現機能を提供するCLRプロシージャを作成する必要があります。

これらのサンプル関数は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

...次のSQLを使用してSQL Serverにインストールされます( '%'で区切られた変数を実際の同等のもので置き換えます:

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)

これはクラシックASPにありますが、サポートされますか?CLRは.NET関数専用だと思いますよね?
Control Freak 2012年

4
CLRプロシージャはSQL Server環境にインストールされ、他のストアドプロシージャまたはユーザー定義関数と同様に呼び出すことができるため、Classic ASPがストアドプロシージャまたはユーザー定義関数を呼び出すことができる場合、CLRプロシージャを呼び出すことができます。
mwigdahl 2012年

1
このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。- レビューから
Federico klez Culloca '19

@FedericoklezCullocaに感謝します。これは古い答えであり、それに応じて更新しました。
mwigdahl

@mwigdahlありがとうございます。古いのですが、レビューキューに表示されました:)
Federico klez Culloca

8

SQL Serverデータベースの正規表現の実装の使用

正規表現-説明
任意の1つの文字に一致する
*任意の文字に一致
+ 前に、式のマッチ少なくとも一つのインスタンス
^ 行の先頭にスタートを
$の 行の末尾に検索
< 一致する場合のみ、この時点での単語が始まる
> マッチ単語は、この時点で停止した場合にのみ
\ n個 改行に一致する
[] 角かっこ内の任意の文字に 一致する
[^ ...] ^
[ABQ]% の後にリストされていない任意の文字に一致する文字列はA、B、またはQのいずれかの文字で始まり、任意の長さにすることができます
[あいうえお]% 文字列の長さは2以上で、AまたはBで始まり、2番目の文字がCまたはDである必要があります
[AZ]% 文字列の長さは任意で、AからZまでの任意の文字で始まる必要があります
[A -Z0-9]% 文字列は任意の長さにすることができ、AからZまでの任意の文字で終了する必要があります%[%$#@]% 文字列は任意の長さにすることができ、少なくとも1つの特殊文字をブラケット 文字列は任意の長さにすることができ、A〜Zの任意の文字または0〜9の数字で始める必要があります
[^ AC]%文字列は任意の長さにすることができますが、A〜Cの文字で始めることはできません
%[AZ]



1

@mwigdahlの回答に対する同様のアプローチで、C#に.NET CLRを実装することもできます。

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

インストール手順はここにあります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.