# Dotnet Source Gen Regex

> Converts Regex instances to use the compile-time source generator. Also use when the user mentions "GeneratedRegex," "regex source generator," "compile-time regex," "AOT regex," "optimize regex," or "source-generated regex." For full AOT analysis, see dotnet-aot-analysis.

- Skill: `im5tu-claude/dotnet-source-gen-regex` (Agent Skill)
- Install (CLI): `npx skillmds@latest add im5tu-claude/dotnet-source-gen-regex`
- Raw SKILL.md: https://api.skillmd.com/api/skills/im5tu-claude/dotnet-source-gen-regex/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: Im5tu (https://skillmd.com/u/im5tu-claude)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/im5tu-claude/dotnet-source-gen-regex

---


# .NET Regex Source Generator

The regex source generator creates compile-time generated regex implementations that are:
- **AOT-compatible**: Works with Native AOT and trimming
- **Debuggable**: Step through the generated matching code
- **Performant**: No runtime compilation overhead

## When to Use

This skill applies when the user:
- Wants to optimize regex performance
- Needs AOT-compatible regex patterns
- Asks about `[GeneratedRegex]` attribute
- Mentions converting `new Regex(...)` to source-generated
- Discusses regex compilation or startup performance

## Workflow

1. **Find regex usages** in the codebase:
   - `new Regex(...)` constructor calls
   - `Regex.IsMatch()`, `Regex.Match()`, `Regex.Replace()` static method calls
   - Other static `Regex.*` methods with inline patterns

2. **For each regex with a compile-time known pattern**:
   - Ensure the containing class is `partial`
   - Create a partial method with `[GeneratedRegex]` attribute:
     ```csharp
     [GeneratedRegex("pattern", RegexOptions.IgnoreCase)]
     private static partial Regex MyRegex();
     ```
   - Name the method descriptively based on what the pattern matches

3. **Replace usages** to call the generated method:
   ```csharp
   // Before
   var regex = new Regex(@"\d+", RegexOptions.Compiled);
   if (regex.IsMatch(input)) { ... }

   // After
   if (MyNumberRegex().IsMatch(input)) { ... }

   [GeneratedRegex(@"\d+")]
   private static partial Regex MyNumberRegex();
   ```

4. **Verify** with `dotnet build`

5. **If build fails**, check:
   - Class is marked `partial`
   - Pattern is a compile-time constant
   - .NET version is 7 or higher

## Key Notes

| Note | Detail |
|------|--------|
| `RegexOptions.Compiled` | Ignored by source gen - remove it |
| .NET Version | Requires .NET 7+ |
| Caching | Generated method caches singleton internally |
| Timeout | Use `[GeneratedRegex("pattern", RegexOptions.None, 1000)]` for timeout (milliseconds) |

## Pattern Conversion Examples

**Instance with options:**
```csharp
// Before
private readonly Regex _emailRegex = new(@"^[\w-\.]+@[\w-]+\.\w+$", RegexOptions.Compiled | RegexOptions.IgnoreCase);

// After
[GeneratedRegex(@"^[\w-\.]+@[\w-]+\.\w+$", RegexOptions.IgnoreCase)]
private static partial Regex EmailRegex();
```

**Static method call:**
```csharp
// Before
if (Regex.IsMatch(input, @"^\d{3}-\d{4}$"))

// After
if (PhoneNumberRegex().IsMatch(input))

[GeneratedRegex(@"^\d{3}-\d{4}$")]
private static partial Regex PhoneNumberRegex();
```

## Error Handling

- **If pattern is not constant**: Cannot use source gen - leave as runtime regex
- **If class is not partial**: Add `partial` modifier to the class declaration
- **If build fails after conversion**: Check error messages for unsupported pattern features

