Skip to main content

How to Replace the Last Occurrence of a Character in a String in JavaScript

While JavaScript's replace() method is great for replacing the first or all occurrences of a substring, there is no built-in function to replace only the last occurrence. This is a common requirement for tasks like formatting file paths or cleaning up generated strings.

This guide will demonstrate the standard and most robust method for this task, which involves finding the index of the last occurrence with lastIndexOf() and then reconstructing the string using slice().

The Core Method: lastIndexOf() and slice()

The most direct and readable way to replace the last occurrence of a substring is to find its position and then manually build a new string with the replacement.

Logic:

  1. Use String.prototype.lastIndexOf() to find the starting index of the last occurrence of the substring.
  2. If the substring is found, "slice" the original string into two parts: the part before the substring and the part after it.
  3. Concatenate the first part, the new replacement string, and the second part to form the final result.

Problem: you have a string and you need to replace only the last instance of the character "b".

// Problem: Replace the last 'm' with '!!!'.
let myString = 'tommy';

Solution:

function replaceLast(str, find, replace) {
let lastIndex = str.lastIndexOf(find);

// If the substring is not found, return the original string
if (lastIndex === -1) {
return str;
}

let before = str.slice(0, lastIndex);
let after = str.slice(lastIndex + find.length);

return before + replace + after;
}

// Example Usage:
let str = 'tommy';
let result = replaceLast(str, 'm', '!!!');

console.log(result); // Output: "tom!!!y"
note

This function correctly identifies the last "b" at index 3 and replaces it.

How the slice() Method Works for Replacement

Let's break down the function replaceLast('tommy', 'm', '!!!'):

  1. str.lastIndexOf('m'): This searches for "m" from the end of the string. It finds it at index 3 and returns this number.
  2. str.slice(0, lastIndex): Slices the string from the beginning (index 0) up to (but not including) index 3. This returns "tom".
  3. str.slice(lastIndex + find.length): Slices the string from after the found substring. The starting point is 3 + 1 = 4. This returns "y".
  4. Concatenation: The final result is "tom" + "!!!" + "y", which produces "to!!!my".

This method works equally well for single characters and for longer substrings.

If your goal is to remove the last occurrence instead of replacing it, you can simply use the same function and provide an empty string ('') as the replacement.

function removeLast(str, find) {
let lastIndex = str.lastIndexOf(find);

if (lastIndex === -1) {
return str;
}

let before = str.slice(0, lastIndex);
let after = str.slice(lastIndex + find.length);

return before + after;
}

// Example Usage:
let path = '/usr/bin/local/bin';
let parentPath = removeLast(path, '/bin');

console.log(parentPath); // Output: /usr/bin/local

Practical Example: A Reusable replaceLast Function

This example creates a robust, reusable function that can be added to a utility library. It handles cases where the substring is not found and works with substrings of any length.

/**
* Replaces the last occurrence of a substring in a string.
* @param {string} str The original string.
* @param {string} find The substring to find.
* @param {string} replace The string to replace it with.
* @returns {string} The new string with the replacement.
*/
function replaceLast(str, find, replace) {
let lastIndex = str.lastIndexOf(find);

if (lastIndex === -1) {
return str;
}

let before = str.slice(0, lastIndex);
let after = str.slice(lastIndex + find.length);

return before + replace + after;
}

// Example Usage:
let sentence = 'The quick brown fox jumps over the lazy fox.';
let corrected = replaceLast(sentence, 'fox', 'dog');

console.log(corrected);

Output:

The quick brown fox jumps over the lazy dog.

Conclusion

Since JavaScript strings are immutable and there is no built-in replaceLast() method, a manual approach is required.

  • The recommended best practice is to find the position of the substring using lastIndexOf() and then reconstruct the string using slice().
  • This method is readable, reliable, and works for both single characters and longer substrings.
  • Always check if lastIndexOf() returns -1 to gracefully handle cases where the substring is not found.