Python
String Manipulation
Substring Search
Programming Tutorial
Python Tips

Check if a word is in a string in Python

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The simplest way to check if a word is in a string in Python is the in operator: "word" in text. However, in checks for substrings, not whole words — "cat" in "concatenate" returns True. For exact whole-word matching, split the string into words or use a regular expression with word boundaries (\b). The right approach depends on whether you need substring matching, whole-word matching, or case-insensitive matching.

The in Operator (Substring Check)

python
1text = "The quick brown fox jumps over the lazy dog"
2
3print("fox" in text)       # True
4print("Fox" in text)       # False — case-sensitive
5print("quick brown" in text)  # True — matches substrings, including spaces
6print("foxes" in text)     # False

in is fast (O(n) where n is the string length) and readable. Use it when substring matching is sufficient.

Case-Insensitive Check

Convert both strings to the same case:

python
1text = "The Quick Brown Fox"
2word = "quick"
3
4print(word.lower() in text.lower())  # True

Or use casefold() for more aggressive Unicode lowering:

python
text = "Straße"  # German for "street"
print("strasse" in text.casefold())  # True — ß folds to ss

Whole-Word Matching with split()

str.split() breaks the string into words by whitespace:

python
1text = "the cat sat on the mat"
2
3# Substring check — matches "cat" inside "concatenate"
4print("cat" in "concatenate")  # True (not what we want)
5
6# Whole-word check
7words = text.split()
8print("cat" in words)          # True
9print("ca" in words)           # False — "ca" is not a whole word

Limitation: split() does not strip punctuation. "Hello, world!".split() gives ["Hello,", "world!"], so "Hello" in words returns False.

Whole-Word Matching with Regex

Use \b (word boundary) for punctuation-aware whole-word matching:

python
1import re
2
3text = "The cat sat on the mat."
4
5print(bool(re.search(r"\bcat\b", text)))   # True
6print(bool(re.search(r"\bca\b", text)))    # False
7print(bool(re.search(r"\bmat\b", text)))   # True — handles trailing period
8
9# Case-insensitive
10print(bool(re.search(r"\bthe\b", text, re.IGNORECASE)))  # True

\b matches at the boundary between a word character (\w) and a non-word character, so punctuation adjacent to the word does not prevent matching.

str.find() and str.index()

These return the position of the substring:

python
1text = "hello world"
2
3# find() returns -1 if not found
4pos = text.find("world")
5print(pos)  # 6
6
7pos = text.find("xyz")
8print(pos)  # -1
9
10# index() raises ValueError if not found
11try:
12    pos = text.index("xyz")
13except ValueError:
14    print("Not found")

Use find() when you need the position, not just a boolean. Use in when you only need True/False.

str.count()

Count occurrences of a substring:

python
1text = "the cat and the hat and the bat"
2
3print(text.count("the"))   # 3
4print(text.count("at"))    # 3 — matches inside "cat", "hat", "bat"
5print(text.count("dog"))   # 0

count() > 0 is equivalent to in but less readable and slightly slower.

str.startswith() and str.endswith()

Check if a string begins or ends with a word:

python
1text = "Hello, World!"
2
3print(text.startswith("Hello"))  # True
4print(text.endswith("World!"))   # True
5
6# Check against multiple prefixes
7print(text.startswith(("Hello", "Hi", "Hey")))  # True

Multiple Words Check

Check if any or all words from a list are in the string:

python
1text = "The quick brown fox jumps over the lazy dog"
2words = ["fox", "dog", "cat"]
3
4# Any word present
5print(any(w in text for w in words))   # True
6
7# All words present
8print(all(w in text for w in words))   # False — "cat" is missing
9
10# Which words are present
11found = [w for w in words if w in text]
12print(found)  # ['fox', 'dog']

Performance Comparison

python
1import timeit
2
3text = "The quick brown fox" * 1000
4
5# 'in' operator — fastest for substring
6timeit.timeit(lambda: "fox" in text, number=100000)
7
8# re.search with word boundary — slower but more precise
9timeit.timeit(lambda: bool(re.search(r"\bfox\b", text)), number=100000)
10
11# split() and 'in' — slowest for long strings (creates a list)
12timeit.timeit(lambda: "fox" in text.split(), number=100000)

For most use cases, the performance difference is negligible. Choose based on correctness requirements (substring vs. whole-word), not speed.

Common Pitfalls

  • Substring matching when whole-word is needed: "cat" in "concatenate" returns True. If you need whole-word matching, use re.search(r"\bcat\b", text) or check against text.split().
  • Case sensitivity: "Hello" in "hello world" returns False. Always use .lower() or re.IGNORECASE for case-insensitive comparisons.
  • Punctuation with split(): "world" in "Hello, world!".split() returns False because split() gives ["Hello,", "world!"]. Strip punctuation first or use regex \b boundaries.
  • Using is instead of in: "fox" is "fox" checks identity (same object), not containment. Use in for membership testing.
  • Empty string always matches: "" in "anything" returns True. If the search term could be empty, check for it explicitly before using in.

Summary

  • Use "word" in text for simple substring checking — fast and readable
  • Use "word" in text.split() for basic whole-word matching (no punctuation handling)
  • Use re.search(r"\bword\b", text) for punctuation-aware whole-word matching
  • Use .lower() or re.IGNORECASE for case-insensitive checks
  • Use any() and all() with generator expressions to check multiple words
  • Use str.find() when you need the position of the match, not just a boolean

Course illustration
Course illustration

All Rights Reserved.