SQL Server Регулярные выражения в T-SQL - PullRequest
121 голосов
/ 12 октября 2008

Существует ли какая-либо библиотека регулярных выражений, записанная в T-SQL (без CLR, без расширенных SP, чисто T-SQL) для SQL Server?

(должен работать с виртуальным хостингом)

Edit:

  • спасибо, я знаю о PATINDEX, LIKE, xp_ sps and CLR` решениях

  • Я также знаю, что это не лучшее место для regex, вопрос теоретический:)

  • также возможна ограниченная функциональность

Ответы [ 6 ]

76 голосов
/ 14 октября 2008

Как насчет функции PATINDEX ?

Сопоставление с образцом в TSQL не является полной библиотекой регулярных выражений, но дает вам основы.

(Из Книг Онлайн)

Wildcard  Meaning  
% Any string of zero or more characters.

_ Any single character.

[ ] Any single character within the specified range 
    (for example, [a-f]) or set (for example, [abcdef]).

[^] Any single character not within the specified range 
    (for example, [^a - f]) or set (for example, [^abcdef]).
15 голосов
/ 16 июня 2015

Если кто-то заинтересован в использовании регулярных выражений с CLR, вот решение. Приведенная ниже функция (C # .net 4.5) возвращает 1, если шаблон соответствует, и 0, если шаблон не соответствует. Я использую его для пометки строк в подзапросах. Атрибут SQLfunction сообщает серверу sql, что этот метод является фактической UDF, которую будет использовать сервер SQL. Сохраните файл как DLL в месте, где вы можете получить к нему доступ из Management Studio.

// default using statements above
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;

namespace CLR_Functions
{   
    public class myFunctions
    {
        [SqlFunction]
        public static SqlInt16 RegexContain(SqlString text, SqlString pattern)
        {            
            SqlInt16 returnVal = 0;
            try
            {
                string myText = text.ToString();
                string myPattern = pattern.ToString();
                MatchCollection mc = Regex.Matches(myText, myPattern);
                if (mc.Count > 0)
                {
                    returnVal = 1;
                }
            }
            catch
            {
                returnVal = 0;
            }

            return returnVal;
        }
    }
}

В Management Studio импортируйте файл dll через программируемость - сборки - новая сборка

Затем выполните этот запрос:

CREATE FUNCTION RegexContain(@text NVARCHAR(50), @pattern NVARCHAR(50))
RETURNS smallint 
AS
EXTERNAL NAME CLR_Functions.[CLR_Functions.myFunctions].RegexContain

Тогда у вас должен быть полный доступ к функции через базу данных, в которой вы сохранили сборку.

Затем используйте в запросах так:

SELECT * 
FROM 
(
    SELECT
        DailyLog.Date,
        DailyLog.Researcher,
        DailyLog.team,
        DailyLog.field,
        DailyLog.EntityID,
        DailyLog.[From],
        DailyLog.[To],
        dbo.RegexContain(Researcher, '[\p{L}\s]+') as 'is null values'
    FROM [DailyOps].[dbo].[DailyLog]
) AS a
WHERE a.[is null values] = 0
14 голосов
/ 12 октября 2008

Существует некоторое базовое сопоставление с образцом, доступное через использование LIKE, где% соответствует любому числу и комбинации символов, _ соответствует любому одному символу, а [abc] может соответствовать a, b или c ... Больше информации на сайте MSDN .

4 голосов
/ 03 июня 2015

В случае, если кто-то еще все еще рассматривает этот вопрос, http://www.sqlsharp.com/ - это бесплатный, простой способ добавления регулярного выражения функций CLR в вашу базу данных.

3 голосов
/ 03 октября 2017

Если вы используете SQL Server 2016 или выше, вы можете использовать sp_execute_external_script вместе с R. Он имеет функции для поиска по регулярному выражению, такие как grep и grepl.

Вот пример для адресов электронной почты. Я опрошу некоторых «людей» через ядро ​​базы данных SQL Server, передам данные этих людей в R, позволю R решить, какие люди имеют недопустимые адреса электронной почты, и пусть R передаст это подмножество людей в SQL Server. «Люди» взяты из таблицы [Application].[People] в базе данных [WideWorldImporters]. Они передаются в движок R как информационный кадр с именем InputDataSet. R использует функцию grepl с оператором not (восклицательный знак!), Чтобы определить, у кого есть адреса электронной почты, которые не соответствуют шаблону поиска строки RegEx.

EXEC sp_execute_external_script 
 @language = N'R',
 @script = N' RegexWithR <- InputDataSet;
OutputDataSet <- RegexWithR[!grepl("([_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4}))", RegexWithR$EmailAddress), ];',
 @input_data_1 = N'SELECT PersonID, FullName, EmailAddress FROM Application.People'
 WITH RESULT SETS (([PersonID] INT, [FullName] NVARCHAR(50), [EmailAddress] NVARCHAR(256)))

Обратите внимание, что соответствующие функции должны быть установлены на хосте SQL Server. Для SQL Server 2016 он называется «Службы SQL Server R». Для SQL Server 2017 он был переименован в «Службы машинного обучения SQL Server».

Заключительные мысли Внедрение Microsoft SQL (T-SQL) не имеет встроенной поддержки RegEx. Это предлагаемое решение может быть не более желательным для OP, чем использование хранимой процедуры CLR. Но он предлагает дополнительный способ решения проблемы.

0 голосов
/ 15 октября 2012

Вы можете использовать функции регулярных выражений VBScript, используя OLE Automation. Это намного лучше, чем затраты на создание и поддержку сборки. Пожалуйста, просмотрите раздел комментариев, чтобы получить лучшую модифицированную версию основного.

http://blogs.msdn.com/b/khen1234/archive/2005/05/11/416392.aspx

DECLARE @obj INT, @res INT, @match BIT;
DECLARE @pattern varchar(255) = '<your regex pattern goes here>';
DECLARE @matchstring varchar(8000) = '<string to search goes here>';
SET @match = 0;

-- Create a VB script component object
EXEC @res = sp_OACreate 'VBScript.RegExp', @obj OUT;

-- Apply/set the pattern to the RegEx object
EXEC @res = sp_OASetProperty @obj, 'Pattern', @pattern;

-- Set any other settings/properties here
EXEC @res = sp_OASetProperty @obj, 'IgnoreCase', 1;

-- Call the method 'Test' to find a match
EXEC @res = sp_OAMethod @obj, 'Test', @match OUT, @matchstring;

-- Don't forget to clean-up
EXEC @res = sp_OADestroy @obj;

Если вы получаете SQL Server blocked access to procedure 'sys.sp_OACreate'... ошибку, используйте sp_reconfigure, чтобы включить Ole Automation Procedures. (Да, к сожалению, это изменение уровня сервера!)

Более подробная информация о методе Test доступна здесь

Счастливое кодирование

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...