提问人:NotX 提问时间:11/15/2023 最后编辑:NotX 更新时间:11/15/2023 访问量:63
MySQL正则表达式在处理重复字符时返回错误的结果
MySQL regexp returns wrong result when working with repeated character
问:
在MySQL 5.7中,我有以下查询:
SELECT `slug` FROM `unittest`.`test_item`
WHERE `slug` REGEXP '^some-slug[0-9]*$'
ORDER BY `slug` DESC LIMIT 1;
这对于带有蛞蝓的物品来说效果很好,但是一旦我有像这样的蛞蝓,就找不到那个了。相反,结果一直都是。
我在 regex101.com 设置了一个示例,它似乎有效。some-slug1
some-slug9
some-slug10
some-slug9
关于MySQL,我在这里错过了什么?
答:
1赞
Luuk
11/15/2023
#1
另一种选择:
SELECT
`slug`,
REGEXP_REPLACE(`slug`,'[a-z]','')
FROM `test_item`
WHERE `slug` REGEXP '^some-slug[0-9]*$'
ORDER BY CAST(REGEXP_REPLACE(`slug`,'[a-z]','') as SIGNED)
请参见:DBFIDDLE
编辑:作为奖励(只是为了学习)
为什么这也是正确的顺序?
SELECT
`slug`,
REGEXP_REPLACE(`slug`,'[a-z]','')
FROM `test_item`
WHERE `slug` REGEXP '^some-slug[0-9]*$'
ORDER BY CAST(REGEXP_REPLACE(`slug`,'[a-z]','') as UNSIGNED)
请参见:DBFIDDLE
提示:只需将 slug 添加到您的选择中,您就会明白原因。CAST(REGEXP_REPLACE(
,'[a-z]','') as UNSIGNED)
2赞
user1191247
11/15/2023
#2
如果将查询更改为:
SELECT `slug`
FROM `unittest`.`test_item`
WHERE `slug` REGEXP '^some-slug[0-9]*$'
ORDER BY SUBSTRING(`slug`, 10) + 0 DESC
LIMIT 1;
SUBSTRING('slug', 10
) ( 是第一位数字的位置) 将数字组件作为字符串返回,然后导致隐式转换为数值(根据 Workbench 为 DOUBLE)。10
+0
您还可以:
ORDER BY CAST(SUBSTRING(`slug`, 10) AS UNSIGNED) DESC
显式 CAST()
将数值分量转换为 .UNSIGNED BIGINT
这是一个 db<>小提琴。
P.S. 有趣的是,对于这个简单的案例,比 .在这种情况下,这不太可能很重要,但作为一般规则值得牢记。如果你有一个非常简单的场景,可以很容易地用简单的字符串函数来解决,那么它们比调用正则表达式要快得多。SUBSTRING()
REGEXP_REPLACE()
评论
1赞
NotX
11/15/2023
再次感谢您的帮助!你可能会在那里添加一个解释。(只是为了完整起见,我理解它是 9 个字符单词之后的位置。10
"some-slug"
1赞
user1191247
11/15/2023
添加了简要说明;-)
评论
LIMIT 1
some-slug10
9 > 10
slug
ORDER BY SUBSTRING(`slug`, 10) + 0 DESC