将正则表达式转换为 SQL 服务器的 LIKE 语句
Translating regex into LIKE statements for SQL Server
我有一个我一直在 Postgres 中使用的正则表达式,我想将其转换为 SQL 服务器,但我相信 SQL 服务器缺乏使用正则表达式的全部功能。但是,我认为我的正则表达式应该足够简单,可以转换为 LIKE
语句。
这是我的正则表达式:^[123ABC]*([456])
。根据我对正则表达式的理解,我在这里使用的两个功能是能够匹配字符串开头的零个或多个字符和捕获组。
这是一个使用 Postgres 的例子:
CREATE TABLE inventory (id INT, pcode VARCHAR(10));
INSERT INTO inventory VALUES (1, 'AABC547');
INSERT INTO inventory VALUES (2, '656ABC49');
INSERT INTO inventory VALUES (3, '11AB727');
INSERT INTO inventory VALUES (4, '7712346');
SELECT
id,
pcode,
COALESCE(
SUBSTRING(pcode from '^[123ABC]*([456])'):: int, 0
) AS desired_val
FROM inventory;
-- id pcode desired_val
-- 1 AABC547 5
-- 2 656ABC49 6
-- 3 11AB727 0
-- 4 7712346 0
这是我尝试重写它以用于 SQL 服务器的尝试,但第一行错误,因为我没有得到与我想要的模式匹配的第一个值 [456]
,但最后一个一.
SELECT
id,
pcode,
CASE
WHEN pcode LIKE '[456]%' THEN CAST(SUBSTRING(pcode, 1, 1) AS INT)
WHEN pcode LIKE '[123ABC]%4%' THEN 4
WHEN pcode LIKE '[123ABC]%5%' THEN 5
WHEN pcode LIKE '[123ABC]%6%' THEN 6
ELSE 0
END AS desired_val
FROM inventory;
-- id pcode desired_val
-- 1 AABC547 4
-- 2 656ABC49 6
-- 3 11AB727 0
-- 4 7712346 0
如果你真的必须用纯T-SQL来做这个,你可以这样写:
SELECT
id,
pcode,
CASE
WHEN pcode LIKE '[456]%' THEN CAST(SUBSTRING(pcode, 1, 1) AS INT)
WHEN pcode LIKE REPLICATE('[123ABC]', CHARINDEX('4', pcode) - 1) + '4%' THEN 4
WHEN pcode LIKE REPLICATE('[123ABC]', CHARINDEX('5', pcode) - 1) + '5%' THEN 5
WHEN pcode LIKE REPLICATE('[123ABC]', CHARINDEX('6', pcode) - 1) + '6%' THEN 6
ELSE 0
END AS desired_val
FROM inventory;
诀窍是使用CHARINDEX()
获取第一个出现[456]
字符的位置,然后使用REPLICATE()
重复[123ABC]
模式a次数等于所需字符之前的字符数。因此,在第一个示例中,'5'
字符位于第五个位置,构造的模式将是:
[123ABC][123ABC][123ABC][123ABC]5%
我有一个我一直在 Postgres 中使用的正则表达式,我想将其转换为 SQL 服务器,但我相信 SQL 服务器缺乏使用正则表达式的全部功能。但是,我认为我的正则表达式应该足够简单,可以转换为 LIKE
语句。
这是我的正则表达式:^[123ABC]*([456])
。根据我对正则表达式的理解,我在这里使用的两个功能是能够匹配字符串开头的零个或多个字符和捕获组。
这是一个使用 Postgres 的例子:
CREATE TABLE inventory (id INT, pcode VARCHAR(10));
INSERT INTO inventory VALUES (1, 'AABC547');
INSERT INTO inventory VALUES (2, '656ABC49');
INSERT INTO inventory VALUES (3, '11AB727');
INSERT INTO inventory VALUES (4, '7712346');
SELECT
id,
pcode,
COALESCE(
SUBSTRING(pcode from '^[123ABC]*([456])'):: int, 0
) AS desired_val
FROM inventory;
-- id pcode desired_val
-- 1 AABC547 5
-- 2 656ABC49 6
-- 3 11AB727 0
-- 4 7712346 0
这是我尝试重写它以用于 SQL 服务器的尝试,但第一行错误,因为我没有得到与我想要的模式匹配的第一个值 [456]
,但最后一个一.
SELECT
id,
pcode,
CASE
WHEN pcode LIKE '[456]%' THEN CAST(SUBSTRING(pcode, 1, 1) AS INT)
WHEN pcode LIKE '[123ABC]%4%' THEN 4
WHEN pcode LIKE '[123ABC]%5%' THEN 5
WHEN pcode LIKE '[123ABC]%6%' THEN 6
ELSE 0
END AS desired_val
FROM inventory;
-- id pcode desired_val
-- 1 AABC547 4
-- 2 656ABC49 6
-- 3 11AB727 0
-- 4 7712346 0
如果你真的必须用纯T-SQL来做这个,你可以这样写:
SELECT
id,
pcode,
CASE
WHEN pcode LIKE '[456]%' THEN CAST(SUBSTRING(pcode, 1, 1) AS INT)
WHEN pcode LIKE REPLICATE('[123ABC]', CHARINDEX('4', pcode) - 1) + '4%' THEN 4
WHEN pcode LIKE REPLICATE('[123ABC]', CHARINDEX('5', pcode) - 1) + '5%' THEN 5
WHEN pcode LIKE REPLICATE('[123ABC]', CHARINDEX('6', pcode) - 1) + '6%' THEN 6
ELSE 0
END AS desired_val
FROM inventory;
诀窍是使用CHARINDEX()
获取第一个出现[456]
字符的位置,然后使用REPLICATE()
重复[123ABC]
模式a次数等于所需字符之前的字符数。因此,在第一个示例中,'5'
字符位于第五个位置,构造的模式将是:
[123ABC][123ABC][123ABC][123ABC]5%