简体   繁体   中英

How to replace last occurrence of a substring in MYSQL?

How can I replace the last occurrence of a substring with blank string in MYSQL?I could not find any such direct function in MYSQL

String: "American Corp National Corp"

Search String: "Corp"

Expected output: "American Corp National"

Could anyone suggest?

这是更短,更易读:

SELECT TRIM(TRAILING 'Corp' FROM 'American Corp National Corp')

Try:

select reverse(concat(
               left(reverse('American Corp National Corp'),
                    instr(reverse('American Corp National Corp'),reverse('Corp'))-1),
               substr(reverse('American Corp National Corp'),
                      instr(reverse('American Corp National Corp'),reverse('Corp'))+
                      length('Corp')))) result

( SQLFiddle )

这是一个 SQL 查询:

select CONCAT(SUBSTRING_INDEX('<TEST_STRING>','<String that you want to replace>',(length('<TEST_STRING>') - length(replace('<TEST_STRING>', '<String that you want to replace>', '')))),'<String to be replaced>',SUBSTRING_INDEX('<TEST_STRING>', '<String that you want to replace>', -1)) as test

This feels like an awful way to do it, but... reverse the string, search for the first occurence of the reverse of the search string using locate , then calculate what index that would be in the non reversed string?

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_reverse

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_locate

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_char-length (Pretty sure you need to use this instead of length to be unicode compliant, but check to be sure!)

Worked example:

String: 0123456789 (char_length = 10)

Search string: 567 (char_length = 3)

Reverse string: 9876543210

Reverse search string: 765

Locate returns index = 2

index of end in real string = 7 (char_length(string) - 1 - index -> 10 - 1 - 2)

index of start in real string = 5 (char_length(string) - 1 - (char_length(search string) - 1) - index -> 10 - 1 - (3 - 1) - 2)

After researching this problem myself and reading the answers above, I created the following function to solve this problem. In my case, I needed to change the last separator in a sequence, so that eg, "Aap, Noot, Mies" would become "Aap, Noot & Mies":

CREATE DEFINER=`root`@`localhost` FUNCTION `change_last_substring`(
    input_string text,  
    separator_old tinytext, 
    separator_new tinytext
) RETURNS text CHARSET utf8
BEGIN

set @output_string=
trim(
    leading separator_new from
    concat
    (
        left(input_string,length(input_string)-length(substring_index(input_string,separator_old,-1))-2),
        separator_new,
        substring_index(input_string,separator_old,-1)
    )
);

RETURN @output_string;

END

The accepted answer doesn't replace @FROM with @TO , it replaces @FROM with empty string. If you need to replace @FROM with @TO , here is a modification of that answer:

SELECT reverse(
           concat(
               concat(
                   left(reverse(value),
                        instr(reverse(value), reverse(@FROM)) - 1),
                   @TO
                 ),
               substr(reverse(value),
                      instr(reverse(value), reverse(@FROM)) +
                      length(@FROM))))
FROM `table`
WHERE `value` like '%' + @FROM + '%'

Notice additional WHERE value like '%' + @FROM + '%' , as this removes an extra character if the substring doesn't occur in the value, eg trying to replace "a" with "b" in "ccc" results in "cc"

More easy and reliable

CONCAT(SUBSTRING_INDEX('American Corp National Corp','Corp',2), "REPLACE_STRING" ,SUBSTRING_INDEX('American Corp National Corp','Corp',-1))

REPLACE_STRING you can change it with replace string or empty for replacing.

If you have a recent version of MySQL (>= v8) / MariaDB (>= v10.0.5) , you can use REGEXP_REPLACE to replace the last occurrence of needle with replacement , like so:

REGEXP_REPLACE(haystack, "^.*needle", "\\1replacement")

This exploits the greediness of * .

If you are using MySQL, and know (or can calculate) the number of occurrences, you can use the optional occurence parameter of REGEXP_REPLACE .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM