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 parameter1
means that it only does one split. - Then
'three'.join(...)
joins the result from the split using thenew
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 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
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 stringold
within thestring
, starting from the indexindex_of_occurrence + 1
.- The while loop will continue to run and increase
occurrence
and set theindex_of_occurrence
until the N-th occurrence is found, or until there are no more occurrences ofold
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)