How to find all occurrences of a substring?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Finding all occurrences of a substring within a string is a fundamental operation in text processing, search engines, and data validation. Python uses str.find() in a loop or re.finditer() for regex-based matching. JavaScript uses indexOf() in a loop or matchAll(). For performance-critical applications with large texts, algorithms like KMP (Knuth-Morris-Pratt) run in O(n + m) time instead of the naive O(n * m). This article covers practical approaches in multiple languages.
Python: Using str.find()
str.find(sub, start) returns the first index of sub at or after start, or -1 if not found. Incrementing start by 1 (not len(substring)) catches overlapping matches.
Python: Using re.finditer()
re.finditer() returns match objects with .start(), .end(), and .group() methods. Use lookahead (?=pattern) for overlapping matches.
JavaScript: Using indexOf()
JavaScript: Using matchAll()
matchAll() requires the g (global) flag and returns an iterator of match objects with an index property.
Java
C#
KMP Algorithm (O(n + m))
KMP avoids re-scanning characters by using a precomputed prefix table. It runs in O(n + m) time, making it optimal for large texts or repeated searches.
Common Pitfalls
- Non-overlapping vs overlapping matches: Incrementing the search position by
len(substring)skips overlapping matches. Increment by 1 for overlapping:"aaa"contains"aa"at positions [0, 1], not just [0]. - Case sensitivity:
str.find()andindexOf()are case-sensitive by default. Use.lower()on both strings orre.IGNORECASEfor case-insensitive matching. - Empty substring:
"hello".find("")returns 0 in Python (every position matches empty). Handle empty substring as a special case if needed. - Performance with large texts: The naive loop approach is O(n * m) in the worst case. For large texts with long patterns, use KMP or Python's built-in
str.count()(which uses optimized C code). - Regex special characters: When using
re.finditer(), special characters in the substring (.,*,+, etc.) are interpreted as regex. Usere.escape(substring)to treat them as literal characters.
Summary
- Python:
str.find()in a loop orre.finditer()for regex patterns - JavaScript:
indexOf()in a loop orString.matchAll(/pattern/g) - Java/C#:
indexOf()/IndexOf()in a loop or regexMatcher/Regex.Matches - Increment by 1 for overlapping matches, by
len(substring)for non-overlapping - Use
re.escape()when searching for literal strings with regex - For performance-critical applications, KMP algorithm runs in O(n + m) time
Related reading
- How to find all permutations of a given word in a given text?
- How to find all positions of the maximum value in a list?
- How to find all possible subsets of a given array?
- How to find all taxicab numbers less than N?
- How to find all vertex-disjoint paths in a graph?
- How to find common strings among two very large files?
- How to find convex hull in a 3 dimensional space
- How to find cycles of a given length in a directed graph? Using networkx

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.