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 parameter1means that it only does one split. - Then
'three'.join(...)joins the result from the split using thenewstring 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 ofold.string[:index]: Gets the portion of the string before the last occurrence ofold.new: The replacement string.string[index+len(old):]: Gets the portion of the string after the last occurrence ofold.- The slices and the
newstring 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 stringoldwithin thestring, starting from the indexindex_of_occurrence + 1.- The while loop will continue to run and increase
occurrenceand set theindex_of_occurrenceuntil the N-th occurrence is found, or until there are no more occurrences ofoldin 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)