Skip to content

How to Replace Last Character or Last N Characters in a String in Python

How to replace the last character or last N characters in a Python string using slicing, re.sub(), rsplit(), and rpartition(), with simple examples and practical tips.

Replacing characters at the end of a Python string is a common requirement, whether you need to change just the very last character or substitute the last several characters with something new. Since strings are immutable, these operations involve creating a new string.

This guide demonstrates the most effective methods using string slicing, re.sub(), rsplit()/join(), and rpartition() to replace the last character(s) of a string.

Understanding the Goal: Replacing String Endings

Given a string, we want to create a new string where either the single last character or the last N characters are replaced by a new character or substring. Because Python strings cannot be changed in place (they are immutable), all these methods construct and return a new string.

Example Data:

original_string = "report_final_v2.docx"
n_chars_to_replace = 4 # e.g., replace "docx"
new_ending = "pdf"
single_char_replacement = "_"

Replace Only the LAST Character

Goal: Replace just the very last character of the string.

This is the most direct and Pythonic way for replacing a single character based on position. Slice the string up to the last character, then concatenate the new character(s).

original = "filename.tx" # Intentionally wrong ending
replacement = "t"

new_string = original[:-1] + replacement

print(f"Original: '{original}'")
print(f"Replace last char with '{replacement}': '{new_string}'")

replacement_multi = "_final"
new_string_multi = original[:-1] + replacement_multi
print(f"Replace last char with '{replacement_multi}': '{new_string_multi}'")

Output:

Original: 'filename.tx'
Replace last char with 't': 'filename.tt'
Replace last char with '_final': 'filename.t_final'
  • original[:-1]: Creates a slice containing all characters except the last one.
  • + replacement: Concatenates the desired replacement character(s) to the end.
  • If the replacement is not a string, convert it first: original[:-1] + str(replacement).

Using re.sub() with $ Anchor

Use a regular expression to match any single character (.) right at the end of the string ($) and replace it.

import re # Required import

original = "version_A"
replacement = "B"

new_string_re = re.sub(r'.$', replacement, original)

print(f"Original: '{original}'")
print(f"Replace last char with '{replacement}' (re.sub): '{new_string_re}'")

print(f"Replace last char of '': '{re.sub(r'.$', replacement, '')}'")

Output:

Original: 'version_A'              
Replace last char with 'B' (re.sub): 'version_B'
Replace last char of '': ''

Using list() Conversion (Less Efficient)

Convert the string to a list of characters (which is mutable), change the last element, then join back to a string. This is generally inefficient for strings due to the overhead of list creation and joining.

original = "item-1"
replacement = "2"

char_list = list(original)
print(f"Original: '{original}' -> List: {char_list}")

char_list[-1] = replacement
print(f"Modified List: {char_list}")

new_string_list = "".join(char_list)
print(f"Replace last char with '{replacement}' (list): '{new_string_list}'")

Output:

Original: 'item-1' -> List: ['i', 't', 'e', 'm', '-', '1']
Modified List: ['i', 't', 'e', 'm', '-', '2']
Replace last char with '2' (list): 'item-2'

Replace the Last N Characters

Goal: Replace a specific number of characters from the end of the string.

Similar to replacing the last character, slice the string up to the last N characters and concatenate the new ending.

original = "document_draft_v1.tmp"
num_chars_to_remove = 3 # Length of "tmp"
new_extension = "docx"

prefix = original[:-num_chars_to_remove]

new_string = prefix + new_extension

print(f"Original: '{original}'")
print(f"Replace last {num_chars_to_remove} with '{new_extension}': '{new_string}'")

new_ending_short = "X"
new_string_short = original[:-num_chars_to_remove] + new_ending_short
print(f"Replace last {num_chars_to_remove} with '{new_ending_short}': '{new_string_short}'")

Output:

Original: 'document_draft_v1.tmp'
Replace last 3 with 'docx': 'document_draft_v1.docx'
Replace last 3 with 'X': 'document_draft_v1.X'

Using rsplit() and join()**

If you want to replace the last occurrence of a specific known substring (which might happen to be the last N characters), you can use rsplit() combined with join().

original = "file_backup.zip.zip" # Want to replace the last '.zip'
old_suffix = ".zip"
new_suffix = ".bak"

parts = original.rsplit(old_suffix, 1)
print(f"Original: '{original}'")
print(f"Parts after rsplit('{old_suffix}', 1): {parts}")

new_string = new_suffix.join(parts)
print(f"Replace last '{old_suffix}' with '{new_suffix}': '{new_string}'")

original2 = "backup.zip_important"
parts2 = original2.rsplit(old_suffix, 1)
new_string2 = new_suffix.join(parts2)
print(f"Replace last '{old_suffix}' (in '{original2}'): '{new_string2}'")

Output:

Original: 'file_backup.zip.zip'
Parts after rsplit('.zip', 1): ['file_backup.zip', '']
Replace last '.zip' with '.bak': 'file_backup.zip.bak'
Replace last '.zip' (in 'backup.zip_important'): 'backup.bak_important'
  • original.rsplit(old_suffix, 1): Splits the string starting from the right, finding the last occurrence of old_suffix. maxsplit=1 ensures it only splits once. It returns a list of parts (usually two parts if the suffix was found).
  • new_suffix.join(parts): Joins the parts back together, inserting new_suffix where the split occurred.
  • This method replaces based on content (old_suffix), not a fixed number of characters.

Using rpartition()

Similar to rsplit, rpartition() splits based on the last occurrence of a separator but always returns a 3-tuple: (part_before, separator, part_after).

original = "config.old.yaml"
separator_to_replace = ".old"
new_separator = ".current"

head, sep, tail = original.rpartition(separator_to_replace)
print(f"Original: '{original}'")
print(f"Head: '{head}', Separator: '{sep}', Tail: '{tail}'")

if sep: # Check if the separator was actually found
    new_string = head + new_separator + tail
else:
    new_string = original # Or head + new_separator + tail which == original + new_separator
print(f"Replace last '{separator_to_replace}' with '{new_separator}': '{new_string}'")

head_nf, sep_nf, tail_nf = "config.yaml".rpartition(separator_to_replace)
print(f"Not found - Head: '{head_nf}', Sep: '{sep_nf}', Tail: '{tail_nf}'")

Output:

Original: 'config.old.yaml'
Head: 'config', Separator: '.old', Tail: '.yaml'
Replace last '.old' with '.current': 'config.current.yaml'
Not found - Head: '', Sep: '', Tail: 'config.yaml'
  • This is useful if you need the separator itself or want to handle the "not found" case differently. You manually reconstruct the string using concatenation (+).

Choosing the Right Method

  • To replace the single last character OR the last N characters by position: Use string slicing my_str[:-N] + replacement. It's direct, efficient, and clearly expresses positional replacement.
  • To replace the last occurrence of a specific substring: Use new.join(s.rsplit(old, 1)). This is idiomatic for single replacements from the right based on content. rpartition is a viable alternative.
  • To replace the last character matching a pattern: Use re.sub(r'pattern$', replacement, string, count=1).

Conclusion

Replacing characters at the end of a Python string involves creating a new string.

  • For replacing based on position (last character or last N characters), string slicing (my_str[:-N] + new_ending) is the most recommended method.
  • For replacing the last occurrence based on content (a specific substring), the new.join(s.rsplit(old, 1)) pattern is effective. rpartition provides more control if needed.
  • Use regular expressions (re.sub) if you need pattern-based replacement at the end.

Choose the method that best reflects whether your replacement logic is based on position count, specific content match, or a more complex pattern.

Navigation