Using RegEx in SQL Server

我正在寻找如何替换/编码文本使用正则表达式的基础上,正则表达式设置/参数如下:

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

我在 RegEx 上看到过一些示例,但是对于如何在 SQLServer 中以同样的方式应用它感到困惑。任何建议都会有帮助。谢谢你。

538528 次浏览

您必须构建一个提供正则表达式功能的 CLR 过程,如 this article所示。

他们的示例函数使用 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 语句安装在 SQLServer 中(将以“%”分隔的变量替换为它们的实际等价物:

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)

您不需要与托管代码交互,因为您可以使用 喜欢:

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 .]%'

编辑:
澄清一下: 如果没有托管代码,SQLServer 不支持正则表达式。根据具体情况,LIKE操作符可以是一个选项,但它缺乏正则表达式所提供的灵活性。

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

Or some other expression instead of A-Z

略作修改的 胡里奥的回答。版本

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

正则表达式在 SQLServer 数据库实现中的使用

正则表达式-描述
. 匹配任意一个字符
匹配任何角色 *
之前至少匹配一个表达式实例
^ 从行首开始
$ 在行尾搜索
< 只有当 word 从这里开始时才匹配
> 只有当文字在此处停止时才匹配
匹配换行符
[] 匹配括号内的任何字符
[ ^ ... ] 匹配 ^ 后面未列出的任何字符
[ ABQ ]% 字符串必须以字母 A、 B 或 Q 开头,并且可以是任意长度
[ AB ][ CD ]% 字符串的长度必须是两个或更多,必须以 A 或 B 开头,并且第二个字符是 C 或 D
[ A-Z ]% 字符串可以是任意长度,并且必须以从 A 到 Z 的任意字母开头
[ A-Z0-9]% 字符串可以是任意长度,必须以从 A 到 Z 的任意字母或0到9的数字开头
[ ^ A-C ]% 字符串可以是任意长度,但不能以字母 A 到 C 开头
字符串可以是任意长度,并且必须以从 A 到 Z 的任意字母结束
% [% $#@]% 字符串可以是任意长度,并且必须包含括在括号 < br/> 中的至少一个特殊字符

A similar approach to @mwigdahl's answer, you can also implement a .NET CLR in C#, with code such as;

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

安装说明可以找到 here