Finding all positions of substring in a larger string in C
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
In C#, the usual way to find every position of a substring is to call IndexOf in a loop and keep moving the starting index forward. The key detail is deciding whether matches are allowed to overlap, because that changes how far the next search should advance.
The Basic IndexOf Loop
For ordinary non-overlapping matches, the algorithm is straightforward:
This prints 0, 4, 8. After each match, the next search begins after the matched substring.
Handling Overlapping Matches
If overlapping matches matter, move the starting position by one character instead of by the pattern length.
This prints 0, 2, which is correct for overlapping occurrences.
Be Explicit About Comparison Rules
IndexOf has overloads that let you choose comparison behavior. That matters because text matching can be case-sensitive, case-insensitive, ordinal, or culture-aware.
For technical text such as identifiers, protocol values, or file formats, StringComparison.Ordinal is usually the safest choice. For case-insensitive technical matching, use StringComparison.OrdinalIgnoreCase.
Being explicit avoids surprises and makes the method contract easier to understand.
Returning an Iterator Instead of a List
If you want lazy consumption of the results, yield return is a nice alternative to building a list up front.
This is useful when callers want to process matches as they are found instead of storing all positions immediately.
When Regex Is the Wrong Tool
If you are searching for a literal substring, regular expressions are often unnecessary. Regex adds power when the pattern itself is variable or rule-based, but it also adds escaping rules and more complexity.
For example, this is a valid regex search:
But if the goal is simply "find every occurrence of cat," IndexOf is clearer and usually the better tool.
Common Pitfalls
The biggest mistake is forgetting to define whether overlaps count. start = index + pattern.Length and start = index + 1 produce different answers, and both can be correct depending on the requirement.
Another issue is leaving StringComparison implicit. That makes the method behavior less obvious and can cause unexpected casing or culture behavior.
Developers also forget to guard against an empty pattern. Without that check, the loop logic can become ambiguous or even infinite.
Finally, do not overuse regex for simple literal searches. It solves a broader problem and is harder to reason about when plain IndexOf already matches the requirement.
Summary
- Loop with
IndexOfto find all substring positions in C#. - Advance by
pattern.Lengthfor non-overlapping matches. - Advance by
1for overlapping matches. - Specify
StringComparisonexplicitly so the matching rule is clear. - Guard against empty patterns before entering the search loop.
Related reading
- Finding an item in a List using C
- Finding property differences between two C objects
- Firing off multiple Tasks asynchronously and waiting for them to complete
- FirstOrDefault Default value other than null
- Floating point comparison functions for C
- FlowLayoutPanel - Automatic Width for controls?
- Fluent Validation vs. Data Annotations
- FluentValidation Check if one of two fields are empty

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.