正则表达式 '\b' 的 T-SQL 等效项

Posted

技术标签:

【中文标题】正则表达式 \'\\b\' 的 T-SQL 等效项【英文标题】:T-SQL Equivalent of regular expression '\b'正则表达式 '\b' 的 T-SQL 等效项 【发布时间】:2020-05-09 12:17:02 【问题描述】:

我正在将使用正则表达式的 CLR 函数转换为 SQL 函数。我知道 SQL Server 不完全支持正则表达式,但我只需要一个案例即可工作,即单词搜索。

搜索字段值:"Id":1234, "Title": "The quick brown"

.NET 中的正则表达式模式:'\b' + '"Id":1234' '\b'

当搜索字段包含 "Id":1234 但不包含 "Id":12345

时,我希望能够匹配

我如何实现这一目标?我已经尝试过了,但是当数字 1234 以空格或 b 而不是逗号结尾时显然不起作用。

DECLARE @match bit = 0
DECLARE @input nvarchar(max) = '"Id":1234, "Title": "The quick brown"'
DECLARE @pattern nvarchar(max) ='"Id":1234'

SELECT @match = 1 FROM (VALUES ('')) table1 (column1)
        WHERE @Input LIKE '%' + @pattern + ',%'

【问题讨论】:

T-SQL 不支持正则表达式;时期。它支持 basic 模式匹配,仅此而已。如果你需要在 SQL Server 中使用某种 REGEX 功能,你需要使用 CLR 函数(有很多关于 REGEX 的示例)。 @Larnu 我在我的问题中特别说过 SQL Server 不支持正则表达式,但我不需要完整的正则表达式支持。我也说我在转换CLR函数,那你告诉我用CLR函数? 这并没有改变我的观点。 SQL Server 只支持基本的模式匹配,如果你想要更多,那么你需要 REGEX,或者类似的东西;这需要一个CLR。我重申这个事实,就好像你知道你不会问如​​何使用 T-SQL 的基本模式匹配来复制 REGEX 功能。 @Larnu 正是我的意思,我只需要基本的模式匹配。我们创建 CLR 是因为我们知道它将涵盖广泛的模式匹配,但是现在我们正在迁移到 Azure SQL w/c 不支持 CLR,我们必须转换 CLR,因此出现了问题。当然,我不期望完整的 REGEX 功能,因此具体情况。 【参考方案1】:

考虑到你有 JSON 数据,为什么不这样解析呢?

DECLARE @JSON nvarchar(MAX) = '"Id":1234, "Title": "The quick brown"';

SELECT *
FROM (VALUES(@JSON)) V(J)
     CROSS APPLY OPENJSON(@JSON)
     WITH (Id int,
           Title varchar(50)) OJ
WHERE OJ.Id = 1234;

【讨论】:

那么我们需要更多的例子,@james。你在这里只给了我们一个,所以我假设它总是 JSON。不过,检查一个值是有效的 JSON 或 xml 就足够简单了。【参考方案2】:

一般来说,仅使用正则表达式解析 JSON 内容并不理想。我们或许可以在这里使用 SQL Server 的增强型 LIKE 运算符:

SELECT *
FROM yourTable
WHERE json LIKE '%"Id":1234[^5]%';

这将返回所有出现的"Id":1234,其后跟除 5 以外的任何字符。请注意,匹配后应始终至少有一个字符,因为键值对需要在 JSON 中关闭。

Demo

【讨论】:

数字的范围为 0 - 999999,因此 1234 之后的数字范围为 0-9。嗯,也许 [^0-9] 应该可以解决问题。我会试试的——好吧,这行得通,不灵活,但我会提供更多的输入。 @james 关于单词​​边界,您实际上可能不是那些假设 JSON 格式正确的人。作为免责声明,使用正则表达式解析 JSON 通常是不好的,但有时我们不得不忍受它。【参考方案3】:

我认为模式'%"Id":1234[^a-zA-Z0-9]%' 可以。

它使用否定字符类[^a-zA-Z0-9],它的工作原理与常规正则表达式一样:)

示例:

declare @tbl table (col varchar(100));
insert into @tbl values 
('"Id":1234, "Title": "The quick brown"'),
('"Id":1234, "Title": "The quick brown"'), 
('Id":1234, "Title": "The quick brown"'), 
('"Id":12345, "Title": "The quick brown"');

select *
from @tbl
where col like '%"Id":1234[^a-zA-Z0-9]%'

【讨论】:

看起来不错,我不希望 id 旁边有一个字母,但感谢额外的保护。 @james 我试图模仿单词边界 :) 当1234 位于字符串末尾时,您也可以使用另一个守卫并允许,例如where ... or col like '%"Id":1234' @MichałTurczyn 假设 OP 只有格式良好的 JSON,您不需要这样的保护。另外,您的答案与我的基本相同,但在 15 分钟后给出。

以上是关于正则表达式 '\b' 的 T-SQL 等效项的主要内容,如果未能解决你的问题,请参考以下文章

C# 等效于 Java 标点正则表达式

使 JavaScript 正则表达式等效于 PHP 正则表达式

使用正则表达式的 T-SQL 搜索 html?

是否有与 Java 正则表达式中的交集 (&&) 运算符等效的 JavaScript 正则表达式?

使用 Beautiful Soup 提取链接的等效正则表达式

是否有 Python 等效于正则表达式的 Perl "/x" 修饰符?