SQL Server에서 RegEx 사용


92

아래의 RegEx 설정 / 매개 변수를 기반으로 RegEx를 사용하여 텍스트를 대체 / 인코딩하는 방법을 찾고 있습니다.

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

RegEx에 대한 몇 가지 예를 보았지만 SQL Server에서 동일한 방식으로 적용하는 방법에 대해 혼란 스러웠습니다. 어떤 제안이라도 도움이 될 것입니다. 감사합니다.



Robyn Page와 Phil Factor 's 에는 VBScript.RegExp 클래스에 의존 하는 훌륭한 TSQL + Windows API 솔루션도 있습니다 . Windows 2000 이후 모든 Windows 버전에서 제공됩니다.
Julio Nobre

TSQL을 통해 RegEx가 절대적으로 필요한 경우 SQL Server 2016 이상에 대한 옵션은 R 서비스사용하는 것 입니다.
Dave Mason

답변:


103

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에 효과적이었습니다.
Rubens Farias

2
정규식을 지원하지 않으므로 SQL Server에서는 작동하지 않습니다.
VVN

10
@VVN LIKE은 정규식이 아니므로 (보다 제한된 패턴 일치 구문 임) 정규식 지원이 없다고해서 이것이 작동하지 않는다는 의미는 아닙니다.
Charles Duffy 2016

@RubensFarias @ mike-young의 의견에 비추어 답변을 업데이트하는 것이 좋지 않습니까?
Sudhanshu Mishra

8

Julio의 답변을 약간 수정했습니다 .

-- 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
BTW, 정규식 개체를 캐시하고 재사용하는 것보다 파괴하고 다시 만드는 것이 훨씬 빠릅니다. 객체를 재사용하는 훨씬 더 많은 숫자로 10,000 번의 비교를 실행했습니다.
Zachary Scott

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)

이것은 Classic ASP에 있습니다. 지원합니까? CLR은 .NET 기능 전용이라고 생각합니다.
Control Freak

4
CLR 프로시 저는 SQL Server 환경에 설치되고 다른 저장 프로 시저 또는 사용자 정의 함수처럼 호출 될 수 있으므로 클래식 ASP가 저장 프로 시저 또는 사용자 정의 함수를 호출 할 수있는 경우 CLR 프로 시저를 호출 할 수 있습니다.
mwigdahl

1
이 링크가 질문에 답할 수 있지만 여기에 답변의 필수 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 무효화 될 수 있습니다. - 리뷰에서
Federico klez Culloca

감사합니다 @FedericoklezCulloca. 이것은 오래된 답변이며 그에 따라 업데이트했습니다.
mwigdahl

@mwigdahl 감사합니다. 나는 그것이 기존의 볼 수 있지만, 그것은 :) 리뷰 대기열에 팝업
페데리코 정보 Klez Culloca

7

SQL Server 데이터베이스 구현에서 정규식 사용

정규식-설명
. 하나의 문자와
일치 * 임의의 문자
일치 + 이전 에 적어도 하나의 표현식 인스턴스 일치
^ 줄 시작에서 시작
$ 줄 끝에서 검색
< 단어가이 지점에서 시작 하는 경우에만 일치
> 단어가이 지점에서 중지되는 경우에만 일치
\ n 줄 바꿈 일치
[] 대괄호 안의 모든 문자 일치
[^ ...] ^
[ABQ] % 뒤에 나열되지 않은 모든 문자 일치 문자열은 문자 A, B 또는 Q로 시작해야하며 길이는 제한되지 않습니다.
[AB] [CD] % 문자열의 길이는 2 개 이상이어야하며 A 또는 B로 시작하고 두 번째 문자로 C 또는 D가 있어야합니다.
[AZ] % 문자열 길이는 제한이 없으며 A에서 Z까지의 문자로 시작해야합니다.
[A -Z0-9] % 문자열은 임의의 길이 일 수 있으며 A에서 Z까지의 문자 또는 0에서 9까지의 숫자로 시작해야합니다.
[^ AC] % 문자열은 임의의 길이 일 수 있지만 A에서 C까지의 문자로 시작할 수 없습니다.
% [AZ] 문자열은 임의의 길이 일 수 있으며 A에서 Z까지의 문자로 끝나야합니다.
% [% $ # @] % 문자열은 임의의 길이 일 수 있으며 다음으로 묶인 특수 문자 중 하나 이상을 포함해야합니다. 브래킷



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.