# C# Regex Matches Example: How to Find All Pattern Occurrences in .NET

> Learn C# regex Matches with this example. Find all pattern occurrences using Regex.Matches in .NET and get each match's value index and captured groups.

- Repository: [Microsoft/vscode](https://github.com/microsoft/vscode)
- Tags: example
- Published: 2026-02-15

---

**Use `Regex.Matches` from the `System.Text.RegularExpressions` namespace to return a `MatchCollection` containing every occurrence of a pattern in a string, then iterate over the collection to access each match's `Value`, `Index`, and captured groups.**

The `Regex.Matches` method is essential for extracting multiple occurrences of patterns from text in C# applications. While the VS Code repository implements similar search functionality in TypeScript files such as [`src/vs/editor/common/model/textModel.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/model/textModel.ts), the underlying regex principles align with .NET's `System.Text.RegularExpressions` engine. This article provides practical C# regex Matches examples derived from real-world pattern matching scenarios.

## What Is `Regex.Matches` in C#?

`Regex.Matches` is a static method that scans an input string for every substring that matches a regular expression pattern. Unlike `Regex.Match`, which stops after finding the first occurrence, `Matches` returns a `MatchCollection` containing all results. This collection exposes properties such as `Count` and allows enumeration to access individual `Match` objects with their `Value`, `Index`, and `Length` properties.

Because the method is static, you do not need to instantiate a `Regex` object for single-use scenarios. However, for high-frequency operations, compiling the pattern improves performance significantly.

## Basic C# Regex Matches Example

The following example demonstrates how to find all four-letter words in a sentence using word boundaries.

```csharp
using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        string input = "This sample text has many four word parts.";
        string pattern = @"\b\w{4}\b";               // four-letter words

        // Get all matches
        MatchCollection matches = Regex.Matches(input, pattern);

        Console.WriteLine($"Found {matches.Count} matches:");
        foreach (Match m in matches)
        {
            // m.Value – the matched substring
            // m.Index – start position in the original string
            Console.WriteLine($"• \"{m.Value}\" at position {m.Index}");
        }
    }
}

```

**Output:**

```

Found 4 matches:
• "This" at position 0
• "text" at position 15
• "many" at position 25
• "four" at position 30

```

## Advanced Pattern Matching Techniques

### Case-Insensitive Matching with `RegexOptions`

To perform a case-insensitive search, pass `RegexOptions.IgnoreCase` as the third argument.

```csharp
string input = "Apple, apple, APPLE, aPpLe";
string pattern = @"apple";

MatchCollection matches = Regex.Matches(
    input,
    pattern,
    RegexOptions.IgnoreCase);   // ignore case

Console.WriteLine($"Matches: {matches.Count}");   // → 5

```

### Extracting Captured Groups from Matches

Use named capture groups to extract specific components from each match, such as year, month, and day from date strings.

```csharp
string input = "2023-04-15 2023/04/16 2023.04.17";
string pattern = @"(?<year>\d{4})[-/.](?<month>\d{2})[-/.](?<day>\d{2})";

foreach (Match m in Regex.Matches(input, pattern))
{
    Console.WriteLine(
        $"Date: {m.Value} (Y:{m.Groups["year"].Value}, M:{m.Groups["month"].Value}, D:{m.Groups["day"].Value})");
}

```

### Optimizing Performance with Compiled Regex

When calling `Matches` repeatedly inside a loop, compile the pattern once to avoid re-parsing the regex on every iteration.

```csharp
Regex regex = new Regex(@"\b\w{4}\b", RegexOptions.Compiled);

for (int i = 0; i < 1000; i++)
{
    var matches = regex.Matches(someLongString);
    // …process matches…
}

```

## VS Code Repository Regex Implementation References

Although VS Code is implemented in TypeScript, its search architecture relies on the same regex principles found in the .NET `System.Text.RegularExpressions` namespace. The following files demonstrate how large-scale applications handle pattern matching across text buffers:

| File Path | Description |
|-----------|-------------|
| [`src/vs/editor/common/model/textModel.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/editor/common/model/textModel.ts) | Contains the core text model used by the editor, including search APIs that rely on regex patterns to locate text within buffers. |
| [`src/vs/workbench/services/search/common/search.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/services/search/common/search.ts) | Implements the "Find in Files" feature using JavaScript `RegExp`, showing how regexes are applied to large text buffers across workspaces. |
| [`src/vs/workbench/services/search/test/common/replace.test.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/services/search/test/common/replace.test.ts) | Unit tests illustrating how regex replace patterns are validated and executed within VS Code's search engine. |
| [`src/vs/workbench/contrib/webview/browser/webviewFindAccessibilityHelp.ts`](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/contrib/webview/browser/webviewFindAccessibilityHelp.ts) | Provides UI strings describing the "Regular Expression" option in the Find widget, demonstrating user-facing regex documentation. |

These references show that whether you are using C# `Regex.Matches` or JavaScript `RegExp`, the fundamental approach of iterating over match collections and handling pattern options remains consistent across languages.

## Summary

- **`Regex.Matches`** returns a `MatchCollection` containing every occurrence of a pattern, unlike `Regex.Match` which stops at the first result.
- Always import **`System.Text.RegularExpressions`** to access the method.
- Access individual match properties such as **`Value`**, **`Index`**, and **`Length`** during iteration.
- Use **`RegexOptions.IgnoreCase`** for case-insensitive searches and **`RegexOptions.Compiled`** for high-performance scenarios with repeated calls.
- Extract structured data using **named capture groups** within your regex patterns.

## Frequently Asked Questions

### What is the difference between `Regex.Match` and `Regex.Matches` in C#?

`Regex.Match` returns a single `Match` object representing the first occurrence of a pattern and stops scanning immediately. `Regex.Matches` scans the entire input string and returns a `MatchCollection` containing every match found. Use `Match` when you only need the first result, and `Matches` when you need to process all occurrences.

### How do I count the total number of matches using `Regex.Matches`?

The `MatchCollection` returned by `Regex.Matches` exposes a `Count` property that provides the total number of matches without requiring manual iteration. Simply access `matches.Count` after calling the method, as shown in the basic usage example.

### Does `Regex.Matches` throw an exception if no matches are found?

No, `Regex.Matches` does not throw an exception when no matches are found. Instead, it returns a valid `MatchCollection` with a `Count` of zero. You can safely iterate over an empty collection using `foreach` or check `if (matches.Count == 0)` to handle cases where the pattern does not exist in the input string.

### When should I use `RegexOptions.Compiled` with `Regex.Matches`?

Use `RegexOptions.Compiled` when you will execute the same regex pattern multiple times—such as inside a loop processing thousands of strings or when calling `Matches` repeatedly on different inputs. This option increases initial compilation overhead but significantly improves execution speed for subsequent matches by compiling the regex to MSIL. For single-use patterns, the standard static `Regex.Matches` call provides better startup performance without the compilation cost.