T-SQL 原生不支援正則表達式,透過 SQLCLR 封裝 System.Text.RegularExpressions.Regex 即可在查詢中直接使用 Regex 比對、擷取、替換。
[SqlFunction]:using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
public partial class UserDefinedFunctions
{
public static readonly RegexOptions Options =
RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline;
[SqlFunction]
public static SqlString RegexMatch(SqlChars input, SqlString pattern)
{
if (input.IsNull || pattern.IsNull) return SqlString.Null;
var regex = new Regex(pattern.Value, Options);
var match = regex.Match(new string(input.Value));
return match.Success ? new SqlString(match.Value) : SqlString.Null;
}
[SqlFunction]
public static SqlString RegexReplace(SqlChars input, SqlString pattern, SqlString replacement)
{
if (input.IsNull || pattern.IsNull) return SqlString.Null;
var regex = new Regex(pattern.Value, Options);
return new SqlString(regex.Replace(new string(input.Value), replacement.Value));
}
[SqlFunction(FillRowMethodName = "FillMatches")]
public static System.Collections.IEnumerable RegexMatches(SqlChars input, SqlString pattern)
{
if (input.IsNull || pattern.IsNull) yield break;
var regex = new Regex(pattern.Value, Options);
foreach (Match m in regex.Matches(new string(input.Value)))
yield return m.Value;
}
public static void FillMatches(object obj, out SqlString value)
=> value = new SqlString((string)obj);
}
-- 比對電子郵件
SELECT dbo.RegexMatch(CAST(email AS SQLCHARS), N'\w+@\w+\.\w+') FROM Customers;
-- 替換電話格式
SELECT dbo.RegexReplace(CAST(phone AS SQLCHARS), N'(\d{3})(\d{4})(\d{4})', N'$1-$2-$3') FROM Contacts;
-- 擷取所有數字
SELECT * FROM dbo.RegexMatches(CAST(notes AS SQLCHARS), N'\d+');
readonly 欄位快取 RegexOptions,避免重複編譯相同模式可考慮 Regex.CompileToAssembly 預編譯。LIKE / PATINDEX 替代簡單模式。SqlChars 流式讀取,避免記憶體壓力。[SqlFunction(TableDefinition = "MatchValue NVARCHAR(4000), Group1 NVARCHAR(4000), Group2 NVARCHAR(4000)",
FillRowMethodName = "FillMatchGroups")]
public static IEnumerable RegexMatchGroups(SqlChars input, SqlString pattern) { ... }
public static void FillMatchGroups(object row, out SqlString v1, out SqlString v2, out SqlString v3) { ... }