JavaScript: replace last occurrence of text in string

See my code snippet below:

var list = ['one', 'two', 'three', 'four']; var str = 'one two, one three, one four, one'; for ( var i = 0; i < list.length; i++) { if (str.endsWith(list[i]) { str = str.replace(list[i], 'finish') } } 

I want to replace the last occurrence of the word one with the word finish in the line, something that will not work for me, because the replace method will replace only its first appearance. Does anyone know how I can change this fragment so that it replaces only the last instance of "one"

+76
javascript string replace
Apr 28 '10 at
source share
14 answers

Well, if the line really ends with a pattern, you can do this:

 str = str.replace(new RegExp(list[i] + '$'), 'finish'); 
+93
Apr 28 '10 at 13:12
source share

You can use String#lastIndexOf to find the last occurrence of a word, and then String#substring and concatenation to build a replacement string.

 n = str.lastIndexOf(list[i]); if (n >= 0 && n + list[i].length >= str.length) { str = str.substring(0, n) + "finish"; } 

... or along these lines.

+34
Apr 28 '10 at 13:12
source share

I know this is stupid, but today I feel creative:

 'one two, one three, one four, one' .split(' ') // array: ["one", "two,", "one", "three,", "one", "four,", "one"] .reverse() // array: ["one", "four,", "one", "three,", "one", "two,", "one"] .join(' ') // string: "one four, one three, one two, one" .replace(/one/, 'finish') // string: "finish four, one three, one two, one" .split(' ') // array: ["finish", "four,", "one", "three,", "one", "two,", "one"] .reverse() // array: ["one", "two,", "one", "three,", "one", "four,", "finish"] .join(' '); // final string: "one two, one three, one four, finish" 

So, all you have to do is add this function to the String prototype:

 String.prototype.replaceLast = function (what, replacement) { return this.split(' ').reverse().join(' ').replace(new RegExp(what), replacement).split(' ').reverse().join(' '); }; 

Then run it like this: str = str.replaceLast('one', 'finish');

One limitation you should know is that since the function is separated by a space, you probably cannot find / replace anything with a space.

Actually, now that I’m thinking about this, you can get around the problem of “space” by dividing it into an empty token.

 String.prototype.reverse = function () { return this.split('').reverse().join(''); }; String.prototype.replaceLast = function (what, replacement) { return this.reverse().replace(new RegExp(what.reverse()), replacement.reverse()).reverse(); }; str = str.replaceLast('one', 'finish'); 
+18
Apr 28 '10 at 13:13
source share

Not as elegant as the regular expression answers above, but it's easier to follow the un-savvy among us:

 function removeLastInstance(badtext, str) { var charpos = str.lastIndexOf(badtext); if (charpos<0) return str; ptone = str.substring(0,charpos); pttwo = str.substring(charpos+(badtext.length)); return (ptone+pttwo); } 

I understand that this is most likely slower and more wasteful than regular expression examples, but I think this may be useful as an illustration of how string manipulations can be performed. (You can also squeeze it a bit, but again, I wanted every step to be clear.)

+11
May 27 '11 at 11:46
source share

I think that I would answer here, since it appeared first in my Google search, and there is no answer (outside the answer of Matt creat :) :), which generally replaces the last occurrence of a character string when the text to replace may not be at the end strings.

 if (!String.prototype.replaceLast) { String.prototype.replaceLast = function(find, replace) { var index = this.lastIndexOf(find); if (index >= 0) { return this.substring(0, index) + replace + this.substring(index + find.length); } return this.toString(); }; } var str = 'one two, one three, one four, one'; // outputs: one two, one three, one four, finish console.log(str.replaceLast('one', 'finish')); // outputs: one two, one three, one four; one console.log(str.replaceLast(',', ';')); 
+8
Aug 09 '13 at 20:51
source share

Here we use a method that uses only separation and union. This is a bit more readable, so I thought it was worth sharing:

  String.prototype.replaceLast = function (what, replacement) { var pcs = this.split(what); var lastPc = pcs.pop(); return pcs.join(what) + replacement + lastPc; }; 
+7
Jan 05 '16 at 23:00
source share

A simple answer without any regular expressions would be:

 str = str.substr(0, str.lastIndexOf(list[i])) + 'finish' 
+4
Aug 16 '18 at 9:33
source share

Could you just change the line and replace only the first occurrence of the reverse search pattern? I think.,.

 var list = ['one', 'two', 'three', 'four']; var str = 'one two, one three, one four, one'; for ( var i = 0; i < list.length; i++) { if (str.endsWith(list[i]) { var reversedHaystack = str.split('').reverse().join(''); var reversedNeedle = list[i].split('').reverse().join(''); reversedHaystack = reversedHaystack.replace(reversedNeedle, 'hsinif'); str = reversedHaystack.split('').reverse().join(''); } } 
+2
Sep 17 '14 at 13:50
source share

Old-fashioned and large code, but as efficient as possible:

 function replaceLast(origin,text){ textLenght = text.length; originLen = origin.length if(textLenght == 0) return origin; start = originLen-textLenght; if(start < 0){ return origin; } if(start == 0){ return ""; } for(i = start; i >= 0; i--){ k = 0; while(origin[i+k] == text[k]){ k++ if(k == textLenght) break; } if(k == textLenght) break; } //not founded if(k != textLenght) return origin; //founded and i starts on correct and i+k is the first char after end = origin.substring(i+k,originLen); if(i == 0) return end; else{ start = origin.substring(0,i) return (start + end); } } 
+1
Jan 05 '14 at 16:23
source share

If speed is important, use this:

 /** * Replace last occurrence of a string with another string * x - the initial string * y - string to replace * z - string that will replace */ function replaceLast(x, y, z){ var a = x.split(""); var length = y.length; if(x.lastIndexOf(y) != -1) { for(var i = x.lastIndexOf(y); i < x.lastIndexOf(y) + length; i++) { if(i == x.lastIndexOf(y)) { a[i] = z; } else { delete a[i]; } } } return a.join(""); } 

This is faster than using RegExp.

+1
Feb 23 '17 at 15:55
source share

A simple solution would be to use the substring method. Since the string ends with a list item, we can use string.length and calculate the end index for the substring without using the lastIndexOf method

str = str.substring(0, str.length - list[i].length) + "finish"

+1
Nov 12 '18 at 13:00
source share

I would suggest using the replace-last npm package.

 var str = 'one two, one three, one four, one'; var result = replaceLast(str, 'one', 'finish'); console.log(result); 
 <script src="https://unpkg.com/replace-last@latest/replaceLast.js"></script> 

This works to replace strings and regular expressions.

0
Mar 19 '18 at 20:32
source share

I did not like any of the answers above, and I came to the following

 function replaceLastOccurrenceInString(input, find, replaceWith) { if (!input || !find || !replaceWith || !input.length || !find.length || !replaceWith.length) { // returns input on invalid arguments return input; } const lastIndex = input.lastIndexOf(find); if (lastIndex < 0) { return input; } return input.substr(0, lastIndex) + replaceWith + input.substr(lastIndex + find.length); } 

Using:

 const input = 'ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty'; const find = 'teen'; const replaceWith = 'teenhundred'; const output = replaceLastOccurrenceInString(input, find, replaceWith); console.log(output); // output: ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteenhundred twenty 

Hope this helps!

0
Jul 05 '19 at 10:55
source share
 str = (str + '?').replace(list[i] + '?', 'finish'); 
-one
Feb 12 '15 at 23:39
source share



All Articles