# Best C# Regex to Match Only Numeric Characters in a String

> Discover the best C# regex to match only numeric characters. Learn how to use the `^\d+$` pattern with `Regex.IsMatch()` for effective string validation in .NET.

- Repository: [.NET Platform/runtime](https://github.com/dotnet/runtime)
- Tags: best-practices
- Published: 2026-02-19

---

**Use the pattern `@"^\d+$"` with `Regex.IsMatch()` to verify that a string contains only numeric characters, where `^` and `$` anchor the match to the start and end, and `\d` matches any Unicode decimal digit.**

The `System.Text.RegularExpressions` namespace in the dotnet/runtime repository provides a highly optimized engine for string validation. When you need to confirm that input contains exclusively numeric characters, leveraging the static `Regex.IsMatch` method offers the best balance of performance and maintainability.

## The Optimal Pattern: `^\d+$`

The most robust pattern for matching only numeric characters is:

```csharp
@"^\d+$"

```

- **`\d`** – Matches any Unicode decimal digit (equivalent to `\p{Nd}`), including international numerals like Arabic-Indic digits (`١٢٣`).
- **`^` and `$`** – Anchors that ensure the match spans the entire string from start to finish, preventing partial matches.

If your requirements strictly limit input to ASCII digits (`0-9`), use a character class instead:

```csharp
@"^[0-9]+$"

```

This rejects any Unicode digits outside the basic Latin range.

## How `Regex.IsMatch` Works in the .NET Runtime

According to the dotnet/runtime source code, the `Regex.IsMatch` method follows a sophisticated execution path designed for efficiency.

In [`Regex.cs`](https://github.com/dotnet/runtime/blob/main/Regex.cs), the `Init` method (lines 25-28) calls `RegexParser.Parse` to convert your pattern string into an internal `RegexTree` representation. This parsed tree is then used by the matching engine.

When you call the static `Regex.IsMatch` overload defined in [`Regex.Match.cs`](https://github.com/dotnet/runtime/blob/main/Regex.Match.cs) (lines 13-16), the implementation forwards your request to `RegexCache.GetOrAdd`. This cache stores compiled regex instances, ensuring that repeated calls with the same pattern reuse the compiled engine rather than re-parsing the pattern. The method returns a Boolean directly without constructing a full `Match` object, minimizing allocation overhead.

The actual execution occurs in [`RegexRunner.cs`](https://github.com/dotnet/runtime/blob/main/RegexRunner.cs), where the low-level engine processes the `RegexTree` against your input string.

## Performance Optimization Tips

**Cache behavior is automatic.** The static `Regex.IsMatch` method automatically caches compiled patterns via the internal `RegexCache`. You do not need to implement manual caching for occasional validation calls.

**Consider `RegexOptions.Compiled` for hot paths.** For high-frequency validation (millions of calls), instantiate the regex with compilation:

```csharp
var digitOnly = new Regex(@"^\d+$", RegexOptions.Compiled);

```

This incurs a startup cost but yields faster execution. For most web or application validation scenarios, the static method's automatic caching is sufficient.

**Culture independence.** The `\d` character class is culture-independent by design. You do not need to specify `RegexOptions.CultureInvariant` when validating numeric characters.

## Practical Implementation Examples

### Simple Validation with Static API

```csharp
using System.Text.RegularExpressions;

bool IsAllDigits(string input) => Regex.IsMatch(input, @"^\d+$");

// Usage
Console.WriteLine(IsAllDigits("12345"));      // True
Console.WriteLine(IsAllDigits("12 34"));      // False (contains space)
Console.WriteLine(IsAllDigits("١٢٣"));        // True (Arabic-Indic digits)

```

### High-Performance Instance with Compilation

```csharp
using System.Text.RegularExpressions;

// Compile once, typically as a static readonly field
var digitOnlyRegex = new Regex(@"^\d+$", RegexOptions.Compiled);

bool IsAllDigits(string input) => digitOnlyRegex.IsMatch(input);

```

### Strict ASCII-Only Validation

```csharp
bool IsAsciiDigits(string input) => Regex.IsMatch(input, @"^[0-9]+$");

```

## Summary

- Use `@"^\d+$"` with `Regex.IsMatch()` to validate strings containing only numeric characters.
- The pattern leverages `^` and `$` anchors to ensure the entire string matches, not just a substring.
- The dotnet/runtime implementation automatically caches regex patterns via `RegexCache`, making the static API efficient for most use cases.
- For ASCII-only validation (0-9), substitute `\d` with `[0-9]`.
- Consider `RegexOptions.Compiled` only when performing millions of validations in performance-critical loops.

## Frequently Asked Questions

### What is the difference between `\d` and `[0-9]` in C# regex?

`\d` matches any Unicode decimal digit (category `\p{Nd}`), including international numerals such as Arabic-Indic, Devanagari, or Thai digits. The character class `[0-9]` matches only the ASCII digits 0 through 9. If your application must handle international input, use `\d`; for strict ASCII validation, use `[0-9]`.

### Does `Regex.IsMatch` cache patterns automatically?

Yes. According to the implementation in [`Regex.Match.cs`](https://github.com/dotnet/runtime/blob/main/Regex.Match.cs), static `IsMatch` overloads delegate to `RegexCache.GetOrAdd`, which maintains an internal cache of compiled regex instances. This means subsequent calls with the same pattern reuse the compiled engine without re-parsing, though the cache has size limits for memory management.

### When should I use `RegexOptions.Compiled` for digit validation?

Use `RegexOptions.Compiled` only when your application performs the same validation millions of times in a tight loop. The option generates MSIL code that executes faster than the interpreter but incurs significant startup cost and memory usage. For typical web validation or occasional checks, the static `Regex.IsMatch` method provides better overall performance.

### How can I prevent empty strings from matching the numeric pattern?

The `+` quantifier in `^\d+$` requires at least one digit, so empty strings return `false`. If you need to allow empty strings as valid input, change the quantifier to `*` (`^\d*$`). Always choose `+` when the presence of at least one numeric character is mandatory.