[英]Regex to match anything (including the empty string) except a specific given string
[英]Regex in SQL Server, match anything except a letter
我正在尝试在SQL Server中编写一些正则表达式以匹配除字母之外的字符串之前或之后的所有内容。
'%ABC%'
不起作用,因为它包含字母。
'%[^az]ABC[^az]%'
不起作用,因为它与结果以ABC
开头或结尾的任何查询都不匹配。 因为[^az]
表示不是字母字符,而是一个字符的任何字符。
解决此问题的正则表达式为:
[^a-z]ABC[^a-z]|ABC[^a-z]|[^a-z]ABC
但是您不能在SQL中这样写:
'%[^a-z]ABC[^a-z]|ABC[^a-z]|[^a-z]ABC%'
要么
'%[^a-z]ABC[^a-z]%|%ABC[^a-z]%|%[^a-z]ABC%'
我不想在SQL中使用OR
,因为我有一个包含以下内容的存储过程:
WHERE var like @var
我会用类似的东西执行它
@var = '%[^a-z]APU[^a-z]%'
而且我宁愿没有多个参数,也不要尝试将多个值传递给单个参数。
有没有办法调整'%[^az]ABC[^az]%'
的正则表达式,以便ABC
可以开始或结束字符串?
您可以这样做:
where ' ' + var + ' ' like '%[^a-z]ABC[^a-z]%'
这也将匹配字符串开头和结尾的模式。
不过,我不确定这是否真的符合您的要求。
您还可以使用此CLR代码在SQL Server中使用真实的正则表达式
请参见代码后,添加到SQL Server实例中的函数中的SQL语句
using System;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
using System.Collections;
using System.Data.SqlTypes;
namespace XXX.DotNet.XXX
{
/// <summary>
/// Cette classe est utilisée pour mettre à disposition une librairie de fonctions d'Expressions Régulières destinées pour SQL Server 2005 (et plus) en CLR
/// </summary>
public class RegularExpressionFunctions
{
/**
<summary>
Cette méthode permet de récupérer toutes les sous-chaines d'une chaine correspondant à une expression régulière (sous forme de chaine concaténée)
</summary>
<param name="pattern">
Cette chaîne de caractères représente l'expression régulière à comparer
</param>
<param name="sentence">
Cette chaîne de caractères représente l'expression à évaluer
</param>
<param name="separator">
Cette chaîne de caractères sera insérée entre chaque sous-chaîne
</param>
<returns>
Soit null si aucune sous-chaine ne correspond, soit une chaine correspondant à la concaténation des différentes sous-chaînes séparées par une chaîne de séparation
</returns>
*/
[SqlFunction(IsDeterministic = true, IsPrecise = true, Name = "RegExMatches")]
public static String RegExMatches(String pattern, String sentence, String separator)
{
Regex rgx = new Regex(pattern);
MatchCollection matches = rgx.Matches(sentence);
int nbFound = matches.Count;
if(nbFound == 0){return null;}// Retourne null si aucune sous-chaîne ne correspond à l'expression régulière
String toReturn = "";
for(int i = 0; i < nbFound; i++)
{
Match match = matches[i];
if(i != 0)
{
toReturn += separator;
}
toReturn += match.Value;
}
return toReturn;// Retourne les sous-chaînes séparées par la chaîne de séparation
}
/**
<summary>
Cette méthode permet de récupérer toutes les sous-chaines d'une chaine correspondant à une expression régulière (sous forme de tableau)
</summary>
<param name="pattern">
Cette chaîne de caractères représente l'expression régulière à comparer
</param>
<param name="sentence">
Cette chaîne de caractères représente l'expression à évaluer
</param>
<returns>
Un tableau de taille égale au nombre de sous-chaîne trouvées, contenant dans chaque case une sous-chaîne correspondant à l'expression régulière
</returns>
*/
[SqlFunction(Name = "RegExMatchesSplit", FillRowMethodName = "NextSplitRow", DataAccess = DataAccessKind.Read)]
public static IEnumerable RegExMatchesSplit(String pattern, String sentence)
{
Regex rgx = new Regex(pattern);
MatchCollection matches = rgx.Matches(sentence);
int nbFound = matches.Count;
//String[][] toReturn = new String[nbFound][];
String[] toReturn = new String[nbFound];
for(int i = 0; i < nbFound; i++)
{
/*toReturn[i] = new String[2];
toReturn[i][0] = sentence;
toReturn[i][1] = matches[i].Value;*/
toReturn[i] = matches[i].Value;
}
return toReturn;// Retourne les sous-chaînes dans un tableau
}
public static void NextSplitRow(Object obj, /*out SqlString sentence, */out SqlString match)
{
/*String[] row = (String[])obj;
sentence = new SqlString(row[0]);
match = new SqlString(row[1]);*/
match = new SqlString(obj.ToString());
}
/**
<summary>
Cette méthode permet de récupérer le nombre de sous-chaînes d'une chaîne correspondant à une expression régulière
</summary>
<param name="pattern">
Cette chaîne de caractères représente l'expression régulière à comparer
</param>
<param name="sentence">
Cette chaîne de caractères représente l'expression à évaluer
</param>
<returns>
Le nombre d'occurences des sous-chaînes trouvée par l'expression régulière dans la chaîne d'entrée
</returns>
*/
[SqlFunction(IsDeterministic = true, IsPrecise = true, Name = "RegExNbMatches")]
public static int RegExNbMatches(String pattern, String sentence)
{
return new Regex(pattern).Matches(sentence).Count;// Retourne le nombre de sous-chaînes trouvées
}
/**
<summary>
Cette méthode permet de savoir si une chaîne de caractère correspond à un pattern d'expression régulière
</summary>
<param name="pattern">
Cette chaîne de caractères représente l'expression régulière à comparer
</param>
<param name="sentence">
Cette chaîne de caractères représente l'expression à évaluer
</param>
<returns>
True si l'expression correspond bien au pattern, false dans le cas contraire
</returns>
*/
[SqlFunction(IsDeterministic = true, IsPrecise = true, Name = "RegExIsMatch")]
public static bool RegExIsMatch(String pattern, String sentence)
{
return new Regex(pattern).IsMatch(sentence);
}
/**
TODO - Documentation
*/
[SqlFunction(IsDeterministic = true, IsPrecise = true, Name = "RegExMatch")]
public static String RegExMatch(String pattern, String sentence)
{
Match match = new Regex(pattern).Match(sentence);
if(!match.Success){return null;}
return match.Value;
}
}
}
使用Framework 3.5编译,以下命令可以提供帮助
"C:\Windows\Microsoft.NET\Framework\v3.5\csc.exe" /t:library RegularExpressionFunctions.cs
编译后,将DLL放入C:\\CLR\\Regex\\
(或其他地方,并根据以下SQL Query进行更改)
然后使用以下代码添加功能,并使用下一个查询进行测试
sp_configure 'clr enabled', 1
RECONFIGURE WITH OVERRIDE
-- Drop des fonctions pré-existantes
IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.RegExMatches')) DROP FUNCTION dbo.RegExMatches
GO
IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.RegExNbMatches')) DROP FUNCTION dbo.RegExNbMatches
GO
IF EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.RegExMatchesSplit')) DROP FUNCTION dbo.RegExMatchesSplit
GO
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.objects WHERE object_id = OBJECT_ID(N'dbo.RegExMatch')) DROP FUNCTION dbo.RegExMatch
GO
-- Drop de l'assembly pré-existante puis recréation de celle-ci
IF EXISTS ( SELECT 1 FROM sys.assemblies asms WHERE asms.name = N'RegExFunction' ) DROP ASSEMBLY [RegExFunction]
CREATE ASSEMBLY RegExFunction FROM 'C:\CLR\Regex\RegularExpressionFunctions.dll' WITH PERMISSION_SET = SAFE
GO
-- Création des fonctions
CREATE FUNCTION dbo.RegExMatches(@pattern NVARCHAR(MAX), @sentence NVARCHAR(MAX), @separator NVARCHAR(MAX)) RETURNS NVARCHAR(MAX)
AS EXTERNAL NAME RegExFunction.[XXX.DotNet.XXX.RegularExpressionFunctions].RegExMatches
GO
CREATE FUNCTION dbo.RegExNbMatches(@pattern NVARCHAR(MAX), @sentence NVARCHAR(MAX)) RETURNS INT
AS EXTERNAL NAME RegExFunction.[XXX.DotNet.XXX.RegularExpressionFunctions].RegExNbMatches
GO
--CREATE FUNCTION dbo.RegExMatchesSplit(@pattern NVARCHAR(MAX), @sentence NVARCHAR(MAX)) RETURNS TABLE (Sujet NVARCHAR(MAX), Match NVARCHAR(MAX))
CREATE FUNCTION dbo.RegExMatchesSplit(@pattern NVARCHAR(MAX), @sentence NVARCHAR(MAX)) RETURNS TABLE (Match NVARCHAR(MAX))
AS EXTERNAL NAME RegExFunction.[XXX.DotNet.XXX.RegularExpressionFunctions].RegExMatchesSplit
GO
CREATE FUNCTION dbo.RegExIsMatch(@pattern NVARCHAR(MAX), @sentence NVARCHAR(MAX)) RETURNS BIT
AS EXTERNAL NAME RegExFunction.[XXX.DotNet.XXX.RegularExpressionFunctions].RegExIsMatch
GO
CREATE FUNCTION dbo.RegExMatch(@pattern NVARCHAR(MAX), @sentence NVARCHAR(MAX)) RETURNS NVARCHAR(MAX)
AS EXTERNAL NAME RegExFunction.[XXX.DotNet.XXX.RegularExpressionFunctions].RegExMatch
GO
使用以下查询测试您的功能
DECLARE @sentence NVARCHAR(MAX)
DECLARE @regex NVARCHAR(MAX)
DECLARE @regex2 NVARCHAR(MAX)
DECLARE @separator NVARCHAR(MAX)
SET @sentence = 'ABABCCADSQDJIOAZF JAIPZDJKL MNJKCXNjnaze iodjazpdjadpazdoa zdjio'
SET @regex = '[A-z]{6}\ '
SET @regex2 = '^[^a-z]*ABC[^a-z]*$'
SET @separator = ';'
SELECT @regex as 'Regex', @sentence as 'Sentence', dbo.RegExMatch(@regex2, match) FROM dbo.RegExMatchesSplit(@regex, @sentence);
SELECT @regex as 'Regex', @sentence as 'Sentence', dbo.RegExMatches(@regex2, dbo.RegExMatches(@regex, @sentence, @separator), @separator)
SELECT @regex as 'Regex', @sentence as 'Sentence', dbo.RegExNbMatches(@regex,@sentence)
SELECT @regex as 'Regex', @sentence as 'Sentence', dbo.RegExIsMatch(@regex,@sentence)
SELECT @regex as 'Regex', @sentence as 'Sentence', dbo.RegExMatch(@regex2, dbo.RegExMatch(@regex,@sentence))
GO
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.