SQL Server 2012:提取正则表达式组

SQL Server 2012:提取正则表达式组,sql,sql-server,regex,sql-server-2012,Sql,Sql Server,Regex,Sql Server 2012,我的数据库中有降价格式的文本。我想提取链接并计算匹配链接的数量。我可以使用类似以下的查询获得包含链接的文本块列表: SELECT post_text FROM posts p WHERE p.body like '%\[%](http%)%' ESCAPE '\' 我如何进入下一步,只提取文本的链接部分(括号中的部分)?如果我能得到这个,我可以计算这个特定链接在我的数据集中的次数 一些样本数据: “访问[谷歌](http://google.com)“->应该返回”http://google.c

我的数据库中有降价格式的文本。我想提取链接并计算匹配链接的数量。我可以使用类似以下的查询获得包含链接的文本块列表:

SELECT post_text
FROM posts p
WHERE p.body like '%\[%](http%)%' ESCAPE '\'
我如何进入下一步,只提取文本的链接部分(括号中的部分)?如果我能得到这个,我可以计算这个特定链接在我的数据集中的次数

一些样本数据:

“访问[谷歌](http://google.com)“->应该返回”http://google.com"
“买一部[iPhone](http://www.apple.com)(我比Android更喜欢它)“->应该返回”http://www.apple.com"
“[举例](http://example.com)“->应该返回”http://example.com"
“这是一条消息”->此消息无需返回任何内容,无链接
“我喜欢饼干(巧克力片)”->此款无需返回任何内容,无链接
“[Frank]说‘你好’”->这一次没有任何回复,没有链接

我使用的是SQL Server 2012(如果版本之间在这方面存在差异)。

假设实际数据不比所述示例更复杂,则不必使用正则表达式:

DECLARE @posts TABLE
(
   post_id INT NOT NULL IDENTITY(1, 1),
   post_text NVARCHAR(4000) NOT NULL,
   body NVARCHAR(2048) NULL
);
INSERT INTO @posts (post_text, body) VALUES (N'first',
                                           N'Visit [Google](http://google.com)');
INSERT INTO @posts (post_text, body) VALUES (N'second',
                                           N'Get an [iPhone](http://www.apple.com)');
INSERT INTO @posts (post_text, body) VALUES (N'third',
                                           N'[Example](http://example.com)');
INSERT INTO @posts (post_text, body) VALUES (N'fourth',
                                           N'This is a message');
INSERT INTO @posts (post_text, body) VALUES (N'fifth',
                                           N'I like cookies (chocolate chip)');
INSERT INTO @posts (post_text, body) VALUES (N'sixth',
                                           N'[Frankie] says ''Relax''');
INSERT INTO @posts (post_text, body) VALUES (N'seventh',
                                           NULL);


SELECT p.post_text,
       SUBSTRING(
                  p.body,
                  CHARINDEX(N'](', p.body) + 2,
                  CHARINDEX(N')', p.body) - (CHARINDEX(N'](', p.body) + 2)
                ) AS [URL]
FROM   @posts p
WHERE  p.body like '%\[%](http%)%' ESCAPE '\';
输出:

post_text  URL
first      http://google.com
second     http://www.apple.com
third      http://example.com
附言:

如果您确实想使用正则表达式,则只能通过SQLCLR来实现。您可以编写自己的或下载预先完成的库。我编写了一个这样的库,它有一个包含正则表达式函数的免费版本。但是只有在找不到T-SQL解决方案的情况下才应该使用这些解决方案,到目前为止,这里的情况并非如此。

AFAIK,在MSSQL中没有类似的方法。您可能希望将子字符串方法与PATINDEX一起使用以获得相同的结果。这看起来很有希望,但我收到了以下错误:
传递给LEFT或substring函数的长度参数无效。
通过谷歌搜索,这可能是由于记录没有链接(我们正在寻找的模式)。@Andy:ok,这很容易纠正。但是,如果您可以更新问题以包含代表每个特定案例的数据,这将非常有帮助。例如,丢失的链接是
()
之间没有任何内容的记录,还是
()
完全丢失?所以:
访问[谷歌]()
访问[谷歌]
或两者兼而有之?还有其他的?我增加了一些额外的示例案例。它完全不包含链接,一个附加的,但没有方括号,方括号中没有附加的。@Andy:谢谢。这很有帮助。但是,我刚刚添加了这3个新条目,代码仍然有效。原始WHERE子句过滤掉所有3个新条目;-)。您是说您并不总是具有WHERE条件,还是缺少测试用例?我甚至在
body
字段中添加了一个带有
NULL
的条目,它仍然有效(首先,我在我的
DECLARE
中从
NOT NULL
字段定义中删除了
NOT
。@Andy:我看到你接受了这一点(谢谢),但仅供参考,如果需要,它仍然可以很容易地进行更新,以说明where子句丢失或由于某种原因未捕获错误条目的情况。