Skip to main content

How to Replace the Last or Nth Occurrence of a Substring in Python

This guide explains how to replace the last occurrence of a substring in a Python string, and how to replace the Nth occurrence. We'll cover using str.rsplit() and str.join() for the last occurrence, and a custom function with str.find() for the Nth occurrence.

Replacing the Last Occurrence with str.rsplit() and str.join()

The most concise and readable way to replace the last occurrence of a substring is to use str.rsplit() to split the string and then str.join() to reconstruct it:

def replace_last(string, old, new):
return new.join(string.rsplit(old, 1))

my_str = 'one two two'
print(replace_last(my_str, 'two', 'three')) # Output: one two three
  • The str.rsplit() splits the string on the delimiter old, starting from the right. The parameter 1 means that it only does one split.
  • Then 'three'.join(...) joins the result from the split using the new string as a separator.

Replacing the Last Occurrence (Alternative: rfind() and slicing)

Another, more manual, approach involves finding the last index of the substring and then using string slicing:

def replace_last(string, old, new):
if old not in string: # Handle case where substring isn't found
return string

index = string.rfind(old) # Gets the last index.
return string[:index] + new + string[index+len(old):]

print(replace_last('one two two', 'two', 'three')) # Output: one two three
print(replace_last('abc abc 123', 'abc', '_')) # Output: abc _ 123
  • if old not in string:: This is crucial. It handles the case where the substring you're trying to replace doesn't exist in the string. Without this check, string.rfind(old) would return -1, and the slicing would produce incorrect results.
  • index = string.rfind(old): Finds the index of the last occurrence of old.
  • string[:index]: Gets the portion of the string before the last occurrence of old.
  • new: The replacement string.
  • string[index+len(old):]: Gets the portion of the string after the last occurrence of old.
  • The slices and the new string are concatenated using the + operator to construct the new string.

Replacing the Nth Occurrence

Replacing a specific (Nth) occurrence is more complex. There's no built-in method for this, so you need a custom function:

def replace_nth(string, old, new, n):
index_of_occurrence = string.find(old) # Finds the index of old, starting from the beginning
occurrence = int(index_of_occurrence != -1)

# find index of Nth occurrence
while index_of_occurrence != -1 and occurrence != n:
index_of_occurrence = string.find(old, index_of_occurrence + 1) # Finds the index of old, but starts searching from the previous result + 1.
occurrence += 1

# index of Nth occurrence found, replace substring
if occurrence == n:
return (
string[:index_of_occurrence] + new +
string[index_of_occurrence+len(old):]
)

# if N occurrences of substring not found in string, return string
return string
  • string.find(old, index_of_occurrence + 1) will find the index of the string old within the string, starting from the index index_of_occurrence + 1.
  • The while loop will continue to run and increase occurrence and set the index_of_occurrence until the N-th occurrence is found, or until there are no more occurrences of old in the string.
  • If the N-th occurrence is found, the return statement inside the if statement is reached, and the string is returned.
  • Otherwise, if the N-th occurrence is not found, the original string is returned.

Here are a few examples:

my_str = 'one one one two'

new_str = replace_nth(my_str, 'one', '_', 1)
print(new_str) # Output: _ one one two

new_str = replace_nth(my_str, 'one', '_', 2)
print(new_str) # Output: one _ one two

new_str = replace_nth(my_str, 'one', '_', 3)
print(new_str) # Output: one one _ two

new_str = replace_nth(my_str, 'one', '_', 100) # 100th occurrence?
print(new_str) # Output: one one one two (original string - not found)

new_str = replace_nth(my_str, 'abc', '_', 100)
print(new_str) # Output: one one one two (original string - "abc" not found)