String methods

Beginner25 min

Clean, split, join, search and transform text with the most useful str methods.

What you will learn
  • Split text into pieces and join pieces back together
  • Strip whitespace and remove prefixes and suffixes
  • Search and replace within a string
  • Compare text without regard to case using casefold
On this page

Real text is messy: stray spaces, inconsistent capitals, file extensions you want to drop. The str type comes with methods for nearly all of it, and learning a dozen of them saves a lot of hand-written code.

A method is a function that belongs to a value, called with a dot: text.strip(). Remember that strings are immutable. Every method here returns a new string and leaves the original alone.

Stripping and removing

strip() removes whitespace from both ends, and lstrip() and rstrip() work on one end.

strip_basic.py
line = " Alice, Bob "
print(line.strip())
print(line)
Output
Alice, Bob
Alice, Bob

The second line shows the original untouched, spaces included.

Given an argument, the strip methods remove any of those characters, not that exact text. To remove an exact prefix or suffix, use removeprefix() and removesuffix() Requires version 3.9 or later. They do nothing if the text is not there, so they are safe to call unconditionally.

strip_vs_remove.py
print("eleven".lstrip("el"))
print("eleven".removeprefix("el"))
print("report.txt".removesuffix(".txt"))
print("https://example.com".removeprefix("https://"))
Output
ven
even
report
example.com

lstrip("el") keeps removing e and l characters from the left until it meets another character, so eleven loses three letters. removeprefix("el") removes only the exact text el.

Split and join

split(sep) cuts a string into pieces at each separator. The result is a list, which Python shows in square brackets. Lists get their own lesson later, so for now just read them.

split_basic.py
print("Alice,Bob,Carol".split(","))
print("a-b-c".split("-", 1))
Output
['Alice', 'Bob', 'Carol']
['a', 'b-c']

An optional second argument limits the number of splits: "a-b-c".split("-", 1) gives two pieces.

Calling split() with no argument is special. It splits on any run of whitespace and ignores leading and trailing space, so it never produces empty pieces. split(" ") splits on every single space, which is why it can produce an empty string.

split_whitespace.py
print("one two".split())
print("one two".split(" "))
Output
['one', 'two']
['one', '', 'two']

sep.join(pieces) goes the other way and glues the pieces back together. Note the odd-looking order: the separator is the object, and the pieces are the argument.

join_basic.py
pieces = "Alice,Bob,Carol".split(",")
print(" & ".join(pieces))
Output
Alice & Bob & Carol

Searching and replacing

search_replace.py
text = "to be or not to be"
print(text.replace("be", "BE"))
print(text.replace("be", "BE", 1))
print(text.find("not"), text.find("xyz"))
print(text.count("to"))
print(text.startswith("to"), text.endswith("be"))
Output
to BE or not to BE
to BE or not to be
9 -1
2
True True
  • replace(old, new) replaces every occurrence; a third argument limits how many.
  • find(sub) returns the index of the first match or -1. Its sibling index(sub) raises ValueError instead.
  • count(sub), startswith(prefix) and endswith(suffix) do what their names say. For a simple membership test, sub in text is clearer than find.

Case and comparison

upper(), lower(), title() and swapcase() change case.

case_methods.py
print("hello world".title())
print("Hello".swapcase())
print("42".isdigit(), "4x".isdigit())
Output
Hello World
hELLO
True False

For comparing text without regard to case, use casefold(). It is a more aggressive lower() designed for exactly this job: the German ß becomes ss, so "straße" and "STRASSE" compare equal.

casefold.py
print("straße".lower() == "STRASSE".lower())
print("straße".casefold() == "STRASSE".casefold())
Output
False
True

Common pitfalls

  • Ignoring the return value. name.strip() on its own line does nothing useful. Write name = name.strip().
  • Mixing up strip("abc") and removeprefix("abc"). One removes a set of characters, the other an exact piece of text.
  • Using find() in a condition. A test like text.find("x") is false for a match at index 0 and true for “not found” (-1). Use "x" in text.
  • Joining non-strings. ",".join([1, 2]) raises TypeError. Convert each item to text first.
ExercisePredict the method results

Predict the output of these four lines, then run the file. Input: none. Expected output: four lines.

predict_methods.py
print(" hi ".strip() + "!")
print("a,b,c".split(",")[1])
print("-".join("abc"))
print("Python".replace("th", "TH").lower())
Show solution
hi!
b
a-b-c
python

strip() removes the spaces before ! is added. split(",") gives three pieces, and [1] picks the second one, counting from 0 just as with a string. join treats the string "abc" as the three pieces a, b and c. In the last line replace makes PyTHon, and lower() then turns every capital into lowercase.

ExerciseNormalise a messy username

A sign-up form hands you the text " Dave Smith\n", with spaces at both ends, repeated inner spaces and a newline at the end. Turn it into a username: all lowercase, single underscores between the words, nothing else. Use split() and join, then casefold() and replace.

Input: raw = " Dave Smith\n". Expected output: dave_smith.

Show solution
normalise_username.py
raw = " Dave Smith\n"
words = raw.split()
username = "_".join(words).casefold()
print(username)
Output
dave_smith

split() with no argument drops the outer whitespace, including the newline, and any repeated spaces. Joining the words with "_" and then calling casefold() finishes the job. Doing it in the order " ".join(raw.split()).casefold().replace(" ", "_") gives the same answer.

Summary

  • Methods return new strings. split and join convert between text and lists.
  • strip takes a set of characters; Requires version 3.9 or later removeprefix and removesuffix take exact text.
  • Use casefold() for case-insensitive comparison and in for membership.

Next: Unicode, bytes and encodings.