在 SQL Server 中使用正则表达式

问题描述 投票:0回答:7

我正在寻找如何根据下面的正则表达式设置/参数使用正则表达式替换/编码文本:

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

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

sql-server regex sql-server-2008 t-sql
7个回答
139
投票

您不需要与托管代码交互,因为您可以使用 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
运算符,但它缺乏正则表达式提供的灵活性。


14
投票

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

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


13
投票

您必须构建一个提供正则表达式功能的 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)

12
投票

稍微修改了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

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

或者其他表达方式代替 A-Z


2
投票

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

安装说明可以在这里

找到

0
投票

我以为我需要正则表达式来执行我的查询(查找具有

<img>
标签但标签中没有
alt
属性的内容),但最终情况并非如此(我找到了一个正则表达式对于上述标准,但它在 SQL 中对我不起作用)。

就我而言,以下查询是完美的。您还可能遇到这样的情况:您实际上并不需要 RegEx 来满足您的情况。由于 WHERE 子句的顺序处理,以下查询有效:

select *
from Content c
where c.Deleted = 0
    and c.content_html like '%<img%'
    and c.content_html not like '%alt=%'
© www.soinside.com 2019 - 2024. All rights reserved.