str.removeprefix()

Strip an exact prefix — the intent-preserving alternative to lstrip that does not surprise you with character-set semantics.

String methodPython 3.9+Live demo
Common call
url.removeprefix("https://")
Returns
new str — the original is unchanged
Replaces
the classic `s[len(prefix):] if s.startswith(prefix) else s` idiom
Watch out
exact substring match — not a set of characters like lstrip
str.removeprefix(prefixprefixThe exact substring to remove from the start. If the string does not start with this exact substring, the original is returned unchanged.type: str · required)
str

Demo

Live evaluation
Try:
Inputs
stringstrthe source
prefixstrexact prefix
Output
'unhappy'.removeprefix('un')
'happy'

removeprefix strips an EXACT substring from the start — at most once. If the string does not start with the prefix, the original is returned unchanged. Unlike lstrip, the argument is a substring, not a character set — "un" removes exactly "un" once, not any leading "u" and "n" characters in any order.

Parameters

NameTypeRequiredDescription
prefixstryesThe exact substring to remove from the start. If the string does not start with this exact substring, the original is returned unchanged.

Return value

strA copy of the string with the exact SUBSTRING `prefix` removed from the start, IF the string starts with it. Otherwise the string is returned unchanged. Removes at most one occurrence.

Common patterns

Strip URL scheme
The canonical use case — clean and unambiguous.
host_path = url.removeprefix("https://")
Drop a namespace prefix
Trim exact known prefixes without slicing math.
name = symbol.removeprefix("my_module.")
Feature-flag toggle detection
Detect and strip a marker prefix in one step.
if key.startswith("_"):
    real_key = key.removeprefix("_")

Examples

1. Basic
"unhappy".removeprefix("un")
Returns
"happy"
2. URL scheme
"https://python.org".removeprefix("https://")
Returns
"python.org"
3. Not a prefix
"hello".removeprefix("xy")
Returns
"hello" # unchanged
4. String == prefix
"hello".removeprefix("hello")
Returns
""
5. Removes once only
"ununhappy".removeprefix("un")
Returns
"unhappy" # not "happy"
6. Empty prefix is no-op
"hello".removeprefix("")
Returns
"hello"

Pitfalls

1. Removes AT MOST ONE occurrence
removeprefix strips the prefix once and stops. Doubled prefixes (or triple, etc.) leave the rest in place. Loop or use a while for multi-removal.
One shot
"ununhappy".removeprefix("un")
"unhappy" # still has "un"
Loop for all
s = "ununhappy"
while s.startswith("un"):
    s = s.removeprefix("un")
"happy"
2. Empty prefix returns the original unchanged
Passing "" is a no-op — every string trivially starts with the empty string, but removing 0 characters leaves the original alone.
Empty is no-op
"hello".removeprefix("")
"hello"
Guard for empty
if prefix:
    s = s.removeprefix(prefix)
explicit intent
3. Different from lstrip — exact match, not character set
This is the whole point of the method. lstrip("un") strips any leading "u" and "n" in any order and any repetition. removeprefix("un") only matches the literal prefix "un".
lstrip over-strips
"unnnnhappy".lstrip("un")
"happy" # ate every leading "u" and "n"
removeprefix is precise
"unnnnhappy".removeprefix("un")
"nnnnhappy" # just the first two chars
4. Not available before Python 3.9
Added in 3.9. On older Pythons use the classic idiom.
AttributeError on 3.8
"unhappy".removeprefix("un")   # 3.8
AttributeError: 'str' object has no attribute 'removeprefix'
Portable idiom
def removeprefix(s, p):
    return s[len(p):] if s.startswith(p) else s
works everywhere

When to use

Use it
  • Stripping a KNOWN, exact leading substring
  • URL/URI scheme removal
  • Namespace or module-prefix trimming
  • Any place lstrip would have been the wrong tool because of character-set semantics
Reach for something else
  • Multi-occurrence removal → loop with while + startswith
  • Character-set removal → str.lstrip is the correct tool
  • Case-insensitive prefix removal → casefold both sides, or use regex
  • Python 3.8 or earlier → use the s[len(p):] idiom instead

Notes

Complexity
O(n) — one linear scan to test the prefix, then one slice
Return
A new string; the original is unchanged (strings are immutable)
CPython impl
Objects/unicodeobject.c :: unicode_removeprefix — introduced with PEP 616
Memory
Allocates one new string when the prefix matched; returns the original when not
Thread-safe
Yes — strings are immutable

FAQ

Because lstrip strips a CHARACTER SET, not a substring. "https://".lstrip("https://") strips leading h, t, p, s, colon, and slash in any combination, which is almost never what people want. removeprefix does exact-prefix removal, which is almost always what people meant when they reached for lstrip.

History

3.9
removeprefix() introduced along with removesuffix() via PEP 616 — replacing hand-rolled slice idioms.