| name | dotnet-source-gen-regex |
| description | 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. |
| license | MIT |
| metadata | {"author":"Im5tu","version":"1.0","repositoryUrl":"https://github.com/im5tu/dotnet-skills"} |
| allowed-tools | Bash(dotnet:*) Read Glob Grep AskUserQuestion |
.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
-
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
-
For each regex with a compile-time known pattern:
-
Replace usages to call the generated method:
var regex = new Regex(@"\d+", RegexOptions.Compiled);
if (regex.IsMatch(input)) { ... }
if (MyNumberRegex().IsMatch(input)) { ... }
[GeneratedRegex(@"\d+")]
private static partial Regex MyNumberRegex();
-
Verify with dotnet build
-
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:
private readonly Regex _emailRegex = new(@"^[\w-\.]+@[\w-]+\.\w+$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
[GeneratedRegex(@"^[\w-\.]+@[\w-]+\.\w+$", RegexOptions.IgnoreCase)]
private static partial Regex EmailRegex();
Static method call:
if (Regex.IsMatch(input, @"^\d{3}-\d{4}$"))
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