web-dev-qa-db-fra.com

SQL Server Expressions régulières dans T-SQL

Existe-t-il une bibliothèque d'expressions régulières écrite en T-SQL (no CLR, pas étendu SP, pure T-SQL) pour SQL Server?

(devrait fonctionner avec l'hébergement partagé)

Modifier:

  • merci je sais à propos de PATINDEX, LIKE,xp_sps and Solutions CLR`

  • Je sais aussi que ce n’est pas le meilleur endroit pour regex, la question est théorique :)

  • fonctionnalité réduite est également acceptée

122
xnagyg

Qu'en est-il de la fonction PATINDEX ?

La correspondance de modèle dans TSQL n'est pas une bibliothèque complète de regex, mais elle en fournit les bases.

(De la documentation en ligne)

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]).
76
Eric Z Beard

Si vous souhaitez utiliser regex avec CLR, voici une solution. La fonction ci-dessous (C # .net 4.5) renvoie un 1 si le modèle correspond, et un 0 si le modèle ne correspond pas. Je l'utilise pour baliser des lignes dans des sous-requêtes. L'attribut SQLfunction indique au serveur SQL que cette méthode est la fonction utilisateur définie par le serveur SQL. Enregistrez le fichier en tant que dll à un emplacement où vous pourrez y accéder à partir de studio de gestion.

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

Dans le studio de gestion, importez le fichier dll via le programme - montages - nouvel assemblage

Puis lancez cette requête:

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

Ensuite, vous devriez avoir un accès complet à la fonction via la base de données dans laquelle vous avez stocké l’Assemblée.

Puis utilisez dans des requêtes comme celle-ci:

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
16
Matt Farguson

Il existe quelques correspondances de motifs de base disponibles avec LIKE, où% correspond à n'importe quel nombre et combinaison de caractères, _ à n'importe quel caractère, et [abc] pourrait correspondre à a, b ou c ... Il y a plus d'informations sur - - site MSDN .

14
Steven Murawski

Dans le cas où quelqu'un d'autre examinerait toujours cette question, http://www.sqlsharp.com/ est un moyen gratuit un moyen simple d'ajouter une expression régulière Fonctions CLR dans votre base de données.

4
John Fisher

Si vous utilisez SQL Server 2016 ou une version ultérieure, vous pouvez utiliser sp_execute_external_script avec R. Il a des fonctions pour les recherches d’expressions régulières, telles que grep et grepl.

Voici un exemple pour les adresses e-mail. Je vais interroger des "personnes" via le moteur de base de données SQL Server, transmettre les données de ces personnes à R, laisser R décider quelles personnes ont une adresse électronique invalide et faire en sorte que R renvoie ce sous-ensemble de personnes à SQL Server. Les "gens" viennent du [Application].[People] table dans le [WideWorldImporters] exemple de base de données. Ils sont transmis au moteur R en tant que structure de données nommée InputDataSet. R utilise la fonction grepl avec l'opérateur "not" (point d'exclamation!) Pour rechercher les personnes dont les adresses électroniques ne correspondent pas au modèle de recherche de chaîne 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)))

Notez que les fonctionnalités appropriées doivent être installées sur l'hôte SQL Server. Pour SQL Server 2016, il s'appelle "Services SQL Server R". Pour SQL Server 2017, il a été renommé "Services d'apprentissage de SQL Server".

pensées de clôture L'implémentation de SQL (T-SQL) par Microsoft ne prend pas en charge nativement RegEx. Cette solution proposée n’est peut-être pas plus souhaitable pour le PO que l’utilisation d’une procédure stockée CLR. Mais cela offre un moyen supplémentaire d’aborder le problème.

4
Dave Mason

Vous pouvez utiliser les fonctionnalités d’expression régulière VBScript à l’aide de OLE Automatisation. C’est bien mieux que le temps système nécessaire à la création et à la maintenance d’un assemblage. Assurez-vous de parcourir la section des commentaires pour obtenir une version mieux modifiée de le principal.

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;

Si vous obtenez SQL Server blocked access to procedure 'sys.sp_OACreate'... erreur, utilisez sp_reconfigure autoriser Ole Automation Procedures. (Oui, malheureusement, c'est un changement de niveau de serveur!)

Plus d'informations sur la méthode Test sont disponibles ici

Code heureux

0
James Poulose