在SQL Server中使用RegEx


92

我正在寻找如何根据以下RegEx设置/参数使用RegEx替换/编码文本:

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

我在RegEx上看到了一些示例,但是对于如何在SQL Server中以相同方式应用它感到困惑。任何的意见都将会有帮助。谢谢。


1
嗨,看看这篇文章:codeproject.com/Articles/42764/…–
Mohsen

还有一个精细TSQL +的Windows API的解决方案罗宾·佩奇和菲尔因素的依赖VBScript.RegExp类,其中,我belieave,是因为Windows 2000中附带每个Windows版本
胡利奥·诺布雷

如果通过TSQL绝对需要RegEx,则SQL Server 2016及更高版本的一种选择是使用R服务
戴夫·梅森

Answers:


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起作用。
鲁本斯·法里亚斯

2
由于它不支持正则表达式,因此无法在sql server中使用。
VVN

10
@VVN LIKE不是正则表达式(它是一种更有限的模式匹配语法),因此缺少正则表达式支持并不意味着它不起作用。
查尔斯·达菲

@RubensFarias根据@ mike-young的评论更新答案不是很好吗?
Sudhanshu Mishra

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 Automation Procedures:

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)

这在Classic ASP中,是否支持?我认为CLR仅适用于.NET功能,对吗?
Control Freak 2012年

4
CLR过程安装在SQL Server环境中,并且可以像其他任何存储过程或用户定义函数一样被调用,因此,如果Classic ASP可以调用存储过程或用户定义函数,则可以调用CLR过程。
mwigdahl

1
尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会无效。- 评分
费德里科求职信Culloca

谢谢@FedericoklezCulloca。这是一个旧的答案,我已经对其进行了相应的更新。
mwigdahl

@mwigdahl对此表示感谢。我看它很旧,但是它突然出现在评论队列中:)
Federico klez Culloca

8

SQL Server数据库实现中的正则表达式使用

正则表达式-描述
匹配任意一个字符
*匹配任意字符
+ 匹配至少一个表达式之前的实例
^ 从行的开头开始
$ 搜索在行的末尾
< 仅当单词在此点开始 时才匹配
>仅当单词在此点处停止时才匹配
\ n 匹配换行符
[] 匹配括号内的任何字符
[^ ...] 匹配^之后未列出的任何字符
[ABQ]% 字符串必须以字母A,B或Q开头,并且可以是任何长度
[A B C D]% 字符串的长度必须为两个或多个,并且必须以A或B开头,并以C或D作为第二个字符
[AZ]% 。字符串可以是任何长度,并且必须以从A到Z的任何字母开头
[A -Z0-9]% 字符串可以是任何长度,并且必须以从A到Z的任何字母开头,或者必须是0到9之间的数字。
[^ AC]%字符串可以是任何长度,但是不能以字母A到C开头
%[AZ] 字符串可以是任何长度,并且必须以从A到Z的任何字母结尾。
%[%$#@]% 字符串可以是任何长度,并且必须包含至少一个包含在其中的特殊字符括号



1

与@mwigdahl的答案类似的方法,您还可以使用C#实现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);
 }
}

安装说明可以在这里找到

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.