79

INSTR()我们可以使用下面的函数找到给定子字符串在 MySQL 中第一次出现的索引。

SELECT instr('Have_a_good_day', '_') AS index_position

它将显示5指定子字符串的第一次出现,在这种情况下是下划线_

我需要获取给定字符(或子字符串)的最后一次出现,例如lastIndexOf(String str)String 类的 Java 方法,但我在 MySQL 中找不到任何内置函数。

在 MySQL 中是否有任何内置功能可以实现这一点?

4

6 回答 6

168

@Marc B 很接近。在 MySQL 中,以下语句返回 12:

SELECT CHAR_LENGTH("Have_a_good_day") - LOCATE('_', REVERSE("Have_a_good_day"))+1;

预期可能使用该值,以下语句在最后一个下划线(即_)之前提取字符串的左侧部分:

SELECT LEFT("first_middle_last", CHAR_LENGTH("first_middle_last") - LOCATE('_', REVERSE("first_middle_last")));

结果是“first_middle”。如果要包含分隔符,请使用:

SELECT LEFT("first_middle_last", CHAR_LENGTH("first_middle_last") - LOCATE('_', REVERSE("first_middle_last"))+1);

如果他们增强了 LOCATE 以提供从右侧开始搜索的选项,那就太好了。

如果您想要最后一个空格之后的字符串的正确部分,更好的解决方案是:

SELECT SUBSTRING_INDEX("first_middle_last", '_', -1);

这将返回“最后一个”。

于 2013-08-24T20:17:10.000 回答
24

如果您不想要 REVERSE 的开销,请使用以下命令:

LEFT
(
   'Have_a_good_day', 
   LENGTH('Have_a_good_day') - LENGTH(SUBSTRING_INDEX('Have_a_good_day','_',-1))-1
)
于 2013-08-31T19:21:15.647 回答
19

我认为您可以通过这种方式使用 substring_index :

select substring_index(string, delimiter,-1)

-1 将从字符串的末尾开始。

于 2012-10-08T04:35:57.617 回答
3

反向/索引的组合?

SELECT LENGTH(string) - SUBSTRING_INDEX(REVERSE(string), delimiter) + 1

考虑到您的情况,将其分解Have_a_good_day

REVERSE('Have_a_good_day') -> yad_doog_a_evaH
SUBSTRING_INDEX('yad_doog_a_evah', '_') -> 4
LENGTH('Have_a_good_day') -> 15
15 - 4 + 1 -> 12

Have_a_good_day
123456789012345
           ^
于 2012-10-08T05:13:15.747 回答
3

我发现这是一个很好的技巧:

SELECT LOCATE(SUBSTRING_INDEX('Have_a_good_day', '_', -1),'Have_a_good_day')-1 AS indexpos;

这将返回最后一次出现的索引 (=12)。基本上,您在最后一个分隔符之后搜索字符串的正确部分,然后在整个字符串中搜索该子字符串的位置,从而获得位置:)

如果您想获取此左侧的子字符串,您可以使用:

SELECT
  SUBSTRING('Have_a_good_day', 1, 
     LOCATE(SUBSTRING_INDEX('Have_a_good_day', '_', -1),'Have_a_good_day')-1) 
  AS sub;
于 2016-12-06T12:59:48.283 回答
0

虽然上述代码对单个字符成功运行,但当我使用它们查找子字符串的最后一次出现时它们失败了。因此,我为此任务推荐以下代码:

SELECT LENGTH("my father is my father")
        - LOCATE('father', REVERSE("my father is my father"))-(LENGTH('father')-1)

这应该返回 17

于 2016-03-25T08:07:03.540 回答