Check if String Contains Substring in Python

Learn how to check if a string contains a substring in Python using the in operator, find(), index(), count(), and regex. See case-sensitive, case-insensitive, multiple substring, whole-word, and pattern matching examples.

Published

Updated

Read time 6 min read

Reviewed byDeepak Prasad

Check if String Contains Substring in Python

The easiest way to check whether a string contains a substring in Python is the in operator. It returns True if the substring exists and False otherwise.

Python does not have a common str.contains() method. Use substring in text instead.

Tested on: Python 3.13.3; kernel 6.14.0-37-generic.


Quick answer: check if a string contains a substring

Use substring in text.

python
text = "Python Tutorial"

if "Python" in text:
    print("Found Python")

if "Java" in text:
    print("Found Java")
Output

The first check prints because "Python" appears in the string. The second check does nothing because "Java" is not present.


Python string contains substring quick reference

Task Use
Check if substring exists substring in text
Check if substring does not exist substring not in text
Case-insensitive contains substring.casefold() in text.casefold()
Find first position text.find(substring)
Find first position or raise error text.index(substring)
Count occurrences text.count(substring)
Check multiple substrings, any match any(s in text for s in substrings)
Check multiple substrings, all match all(s in text for s in substrings)
Whole-word match re.search(r"\bword\b", text)
Pattern match re.search(pattern, text)
Starts with substring text.startswith(prefix)
Ends with substring text.endswith(suffix)

Check if string contains substring using in

The in operator is the recommended method for normal checks. It returns True or False, is readable, and is case-sensitive.

python
text = "Python Tutorial"

print("Python" in text)
print("Tutorial" in text)
print("Java" in text)
Output

Use in when you only need to know whether the substring exists. For prefix checks at the start of a string, see Python startswith().


Check if string does not contain substring

Use not in for negative checks. It is clearer than testing find() against -1.

python
line = "INFO: service started"

if "ERROR" not in line:
    print("No error in this line")

if "WARN" not in line:
    print("No warning in this line")
Output

Useful for filtering log lines, skipping values, and validating input.


Python has no str.contains() method

Some languages expose contains(), indexOf(), or includes(). Python’s normal syntax is substring in string.

python
text = "hello world"

# Correct
print("world" in text)

# Wrong — strings have no contains() method
try:
    text.contains("world")
except AttributeError as exc:
    print(type(exc).__name__)
Output

Do not write text.contains(substring) in Python.


Case-sensitive substring check

The in operator is case-sensitive.

python
text = "Python Tutorial"

print("Python" in text)
print("python" in text)
Output

Use exact casing when case matters, such as product codes, file extensions, or protocol names.


Case-insensitive substring check

Use lower() for simple ASCII-style checks. Use casefold() for more robust case-insensitive matching. Normalize both the text and the substring.

python
text = "Python Tutorial"
needle = "python"

print(needle.lower() in text.lower())
print(needle.casefold() in text.casefold())
Output

Do not convert only one side when the substring may come from user input or a variable.


find() vs in

Method Return value Best for
substring in text True or False Simple contains check
text.find(substring) Index or -1 Need position without exception
python
text = "Python Tutorial"

print("Tutorial" in text)
print(text.find("Tutorial"))
print(text.find("Java"))
Output

Use in when you only need existence. Use find() when you need the starting index. Do not choose find() just to get True/False unless you also need the position.

A common mistake is writing if text.find("x"): — that fails when the match is at index 0 because 0 is falsy.


index() vs find()

Method If found If not found Best for
find() Returns index Returns -1 Safe lookup
index() Returns index Raises ValueError Missing substring should be an error
python
text = "Python Tutorial"

print(text.index("Python"))

try:
    text.index("Java")
except ValueError as exc:
    print(type(exc).__name__)
Output

Use index() when a missing substring should stop normal flow. Use find() when missing text is an expected outcome.


Count how many times a substring appears

text.count(substring) returns the number of non-overlapping occurrences. It is case-sensitive.

python
text = "banana"

print(text.count("a"))
print(text.count("na"))
print(text.count("z"))

text2 = "Banana BANANA"
print(text2.lower().count("ana"))
Output

count() > 0 can test existence, but use in when you only need a yes-or-no answer. Use count() when the number of matches matters.


Check multiple substrings

Use any() when at least one substring should match. Use all() when every substring must match.

python
text = "Python data tutorial"
keywords = ["Python", "Java"]
required = ["Python", "tutorial"]

print(any(word in text for word in keywords))
print(all(word in text for word in required))
Output

This pattern works well for keyword filters and simple validation rules. See Python any() and all() for more on these helpers.


Whole-word substring match

The in operator checks characters, not word boundaries.

python
text = "concatenate"

print("cat" in text)

import re
print(bool(re.search(r"\bcat\b", text)))
print(bool(re.search(r"\bcat\b", "a cat sat")))
Output

"cat" appears inside "concatenate", but the whole-word regex matches only standalone "cat". For building strings from matched pieces, see Python concatenate strings.


Substring pattern match using regex

Use re.search() when you need a pattern, not a fixed substring. Good for digits, email-like patterns, whole words, flexible spacing, and prefix or suffix rules.

python
import re

text = "Contact: user@example.com"

print(bool(re.search(r"\d+", text)))
print(bool(re.search(r"[\w.-]+@[\w.-]+\.\w+", text)))
Output

Do not use regex for simple fixed substring checks. Use in first, and reach for Python regex only when the match rule is more flexible.


Find all substring positions

Use find() in a loop when you need every starting position. Built-in search finds non-overlapping positions when you advance the start index correctly.

python
text = "banana"
needle = "ana"
start = 0
positions = []

while True:
    pos = text.find(needle, start)
    if pos == -1:
        break
    positions.append(pos)
    start = pos + 1

print(positions)
Output

For overlapping matches, use custom logic or regex. Built-in count() counts non-overlapping occurrences only.


Check overlapping substring matches

python
text = "aaaa"
needle = "aa"

print(text.count(needle))

import re
print(len(re.findall(f"(?=({needle}))", text)))
Output

count() returns 2 for non-overlapping "aa" in "aaaa". The regex lookahead finds overlapping starts when that behavior matters.


Substring vs subsequence

A substring is contiguous. A subsequence is not necessarily contiguous.

python
word = "Hello"

print("ell" in word)
print("Hlo" in word)

def is_subsequence(text, pattern):
    it = iter(text)
    return all(ch in it for ch in pattern)

print(is_subsequence(word, "Hlo"))
Output

"ell" is a substring of "Hello". "Hlo" is a subsequence but not a substring. Most everyday “contains” checks mean substring, not subsequence.


Practical examples

python
log = "ERROR: database timeout"
user_input = "I love Python"
email = "user@example.com"
urls = ["https://example.com", "http://test.local/page"]
files = ["report.txt", "notes.md", "photo.jpg"]

print("ERROR" in log)
print("Python" in user_input.lower())
print("@" in email)
print([url for url in urls if "example.com" in url])
print([name for name in files if "report" in name])
Output

These patterns fit logs, user input, email checks, URL filtering, and filename searches.


Common mistakes to avoid

  • Looking for text.contains() in Python.
  • Using find() incorrectly: if text.find("x"): fails when the match is at index 0.
  • Forgetting that checks are case-sensitive.
  • Using lower() on only one side.
  • Using in when you need whole-word matching.
  • Using regex for simple substring checks.
  • Forgetting that count() counts non-overlapping occurrences.
  • Searching for a non-string value inside a string.
  • Treating empty substring as a normal search term.
  • Using index() without handling ValueError.
  • Using a find() result of -1 as a slice index.

Summary

Use substring in text for normal substring checks. Use not in for negative checks. Use casefold() when case should not matter. Use find() or index() when you need the position. Use count() when you need the number of occurrences. Use regex only for patterns or whole-word matching. For extracting part of a string, see Python substring and slicing.


References


Frequently Asked Questions

1. How do you check if a string contains a substring in Python?

Use substring in text. It returns True when the substring exists and False otherwise.

2. Does Python have a str.contains() method?

No. Python strings do not have contains(). Use the in operator instead of text.contains(substring).

3. How do you check if a string contains a substring case-insensitively?

Normalize both values the same way, for example substring.casefold() in text.casefold().

4. What is the difference between find() and index() in Python?

find() returns -1 when the substring is missing. index() raises ValueError when the substring is missing.

5. When should you use regex instead of in?

Use regex when you need a pattern, whole-word matching, or flexible formatting. Use in for simple fixed substring checks.

6. What is the difference between substring and subsequence?

A substring is contiguous. A subsequence can skip characters, so "Hlo" is a subsequence of "Hello" but not a substring.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …