SQL 服务器使用正则表达式从字符串中提取整数
SQL Server extract integers from string using regular expression
我有一个字符串(unc 文件路径),我需要提取一些整数,这些整数将以半可预测的方式嵌入到字符串中。
示例字符串:
\servername\folder1\FTP\folder22/862450_FileBundle.zip
--OR-- : \servername\folder1\FTP\folder222450_FileBundle.zip
--OR-- : servername/folder1/FTP/folder2/512/862450_FileBundle.zip
以下正则表达式正则表达式将匹配由正斜杠或反斜杠限定的任何整数值:(\/|\)\d+(\/|\)
所以上面的正则表达式将匹配“\512\”、“\512/”、“/512/”甚至“/512\”。
我尝试了以下 SQL 和其他变体但没有成功:
DECLARE @testString varchar(50) = '\servername\folder1\FTP\folder22/862450_FileBundle.zip'
SELECT PATINDEX('%(\/|\)\d+(\/|\)%', @testString)
我对 REGEX 和 SQL 不是很熟悉,所以我什至不确定这是否可行。
除了写一个UDF来遍历字符,我唯一能想到的就是暴力破解...
(用户定义的函数可能是您最差的选择。)
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=face1befe5e7c74f457846fc37eca649
SELECT
*,
SUBSTRING(test.unc_file_path, headMatch.pos+1, headMatch.chars)
FROM
test
OUTER APPLY
(
SELECT
MIN(pos), MIN(chars)
FROM
(
SELECT
PATINDEX('%' + head + body + tail + '%', test.unc_file_path) AS pos, chars
FROM
(
SELECT '\'
UNION ALL SELECT '/'
)
head(head)
CROSS JOIN
(
SELECT 1, '[0-9]'
UNION ALL SELECT 2, '[0-9][0-9]'
UNION ALL SELECT 3, '[0-9][0-9][0-9]'
UNION ALL SELECT 4, '[0-9][0-9][0-9][0-9]'
UNION ALL SELECT 5, '[0-9][0-9][0-9][0-9][0-9]'
)
body(chars, body)
CROSS JOIN
(
SELECT '\'
UNION ALL SELECT '/'
)
tail(tail)
)
match
WHERE
pos > 0
)
headMatch(pos, chars)
SQL 服务器没有正则表达式那么好的模式匹配能力。您可以搜索模式:
[/\][0-9]%[/\]
也就是说,斜杠后跟一个数字,然后是任何其他字符串,再后跟一个斜杠。这将匹配第一个数字之后的任何字符,但您的示例没有 /1abc/
.
形式
如果这足够了,那么就可以了:
select v.*,
left(v2.str2, patindex('%[/\]%', v2.str2) - 1)
from (values ('\servername\folder1\FTP\folder22/862450_FileBundle.zip')) v(str) cross apply
(values (stuff(v.str, 1, patindex('%[/\][0-9]%[/\]%', v.str), ''))) v2(str2)
我有一个字符串(unc 文件路径),我需要提取一些整数,这些整数将以半可预测的方式嵌入到字符串中。
示例字符串:
\servername\folder1\FTP\folder22/862450_FileBundle.zip
--OR-- : \servername\folder1\FTP\folder222450_FileBundle.zip
--OR-- : servername/folder1/FTP/folder2/512/862450_FileBundle.zip
以下正则表达式正则表达式将匹配由正斜杠或反斜杠限定的任何整数值:(\/|\)\d+(\/|\)
所以上面的正则表达式将匹配“\512\”、“\512/”、“/512/”甚至“/512\”。
我尝试了以下 SQL 和其他变体但没有成功:
DECLARE @testString varchar(50) = '\servername\folder1\FTP\folder22/862450_FileBundle.zip'
SELECT PATINDEX('%(\/|\)\d+(\/|\)%', @testString)
我对 REGEX 和 SQL 不是很熟悉,所以我什至不确定这是否可行。
除了写一个UDF来遍历字符,我唯一能想到的就是暴力破解...
(用户定义的函数可能是您最差的选择。)
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=face1befe5e7c74f457846fc37eca649
SELECT
*,
SUBSTRING(test.unc_file_path, headMatch.pos+1, headMatch.chars)
FROM
test
OUTER APPLY
(
SELECT
MIN(pos), MIN(chars)
FROM
(
SELECT
PATINDEX('%' + head + body + tail + '%', test.unc_file_path) AS pos, chars
FROM
(
SELECT '\'
UNION ALL SELECT '/'
)
head(head)
CROSS JOIN
(
SELECT 1, '[0-9]'
UNION ALL SELECT 2, '[0-9][0-9]'
UNION ALL SELECT 3, '[0-9][0-9][0-9]'
UNION ALL SELECT 4, '[0-9][0-9][0-9][0-9]'
UNION ALL SELECT 5, '[0-9][0-9][0-9][0-9][0-9]'
)
body(chars, body)
CROSS JOIN
(
SELECT '\'
UNION ALL SELECT '/'
)
tail(tail)
)
match
WHERE
pos > 0
)
headMatch(pos, chars)
SQL 服务器没有正则表达式那么好的模式匹配能力。您可以搜索模式:
[/\][0-9]%[/\]
也就是说,斜杠后跟一个数字,然后是任何其他字符串,再后跟一个斜杠。这将匹配第一个数字之后的任何字符,但您的示例没有 /1abc/
.
如果这足够了,那么就可以了:
select v.*,
left(v2.str2, patindex('%[/\]%', v2.str2) - 1)
from (values ('\servername\folder1\FTP\folder22/862450_FileBundle.zip')) v(str) cross apply
(values (stuff(v.str, 1, patindex('%[/\][0-9]%[/\]%', v.str), ''))) v2(str2)