MySQL中给定子字符串的最后一个索引


70

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

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

它会显示5指定子字符串的第一次出现,在此情况下为下划线_

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

在MySQL中是否有任何内置功能可实现此目的?


如果有人有解决方案,请添加它作为答案。
2013年

Answers:


150

@马克·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);

这将返回“ last”。


@Tiny,我确定您现在可能已经找到答案了。我遇到了同样的问题,想发布解决方案。
简短的

确保我的解决方案是您答案中的第一个。感谢你的回答。
2013年

2
SUBSTRING_INDEX非常有用!我们在php中有类似的东西吗?
mikewasmike 2015年

1
@mikewasmike在PHP,使用explode; 在最后一个逗号end(explode(',', $string))后将获取所有内容$string
Brilliand

3
请记住,LENGTH()返回BYTES中的长度,如果在UTF-8列上使用这些函数,则结果可能是错误的,因为UTF-8字符可以具有1到3个字节,为了安全起见,可以在几个不同的位置上使用这些函数字符集,请改用CHAR_LENGTH()。
Eduardo Leggiero

21

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

LEFT
(
   'Have_a_good_day', 
   LENGTH('Have_a_good_day') - LENGTH(SUBSTRING_INDEX('Have_a_good_day','_',-1))-1
)

这正是我所拥有的,我认为比使用更好reverse
Fr0zenFyr 2013年

4
这与公认的答案不同,因为没有定界符的字符串(例如Have,)变为空字符串而不是Have
l33t 2015年

12

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

select substring_index(string, delimiter,-1)

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


当然,我知道可以,但是它显示子字符串本身(提取完成后),而不显示该子字符串的索引位置。在这种情况下,它将显示day但我需要显示12指定的子字符串的索引。
2012年

您的文字多长时间?您可以反转它,然后使用instr或定位函数吗?我知道这不是最理想的方法,但是它可以工作。
rizalp1

在任何情况下,我都无法考虑反转字符串,因为我需要根据找到的最后一个索引在字符串中提取其他文本。
2012年

我需要获取字符串中最后一个字符的索引之前和之后的所有内容,这对我有所帮助
chiliNUT

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
           ^

SUBSTRING_INDEX('yad_doog_a_evah', '_')发出错误Incorrect parameter count in the call to native function 'SUBSTRING_INDEX'。它需要像的第三参数SUBSTRING_INDEX('yad_doog_a_evah', '_', 1)产生子串yad,而不是第一个索引的_4在这种情况下。谢谢回复。
2012年

你有解决方案吗。我可以做到,但是丑陋的方式是可恨和可避免的。谢谢。
2012年

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;

0

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

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

这应该返回17

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.