using-generated-regex
SKILL.md
Using GeneratedRegex (Source Generator)
Use GeneratedRegexAttribute for compile-time regex generation instead of runtime new Regex().
Why GeneratedRegex?
| Aspect | Runtime Regex | GeneratedRegex |
|---|---|---|
| Compilation | Runtime | Compile-time |
| Performance | Slower first match | Pre-compiled, faster |
| AOT Support | Limited | Full support |
| Memory | Allocates at runtime | No runtime allocation |
| .NET Version | All | .NET 7+ |
Basic Pattern
public partial class EmailValidator
{
[GeneratedRegex(@"^[\w\.-]+@[\w\.-]+\.\w+$", RegexOptions.IgnoreCase)]
private static partial Regex EmailPattern();
public bool IsValidEmail(string email)
{
return EmailPattern().IsMatch(email);
}
}
Requirements:
- Class must be
partial - Method must be
static partialreturningRegex - .NET 7 or later
Common Patterns
Email Validation
public partial class ValidationPatterns
{
[GeneratedRegex(@"^[\w\.-]+@[\w\.-]+\.\w+$", RegexOptions.IgnoreCase)]
public static partial Regex Email();
}
Phone Number
[GeneratedRegex(@"^\d{3}-\d{3,4}-\d{4}$")]
public static partial Regex PhoneNumber();
URL Pattern
[GeneratedRegex(@"^https?://[\w\.-]+(?:/[\w\.-]*)*$", RegexOptions.IgnoreCase)]
public static partial Regex Url();
Whitespace Normalization
[GeneratedRegex(@"\s+")]
private static partial Regex WhitespacePattern();
public string NormalizeWhitespace(string input)
{
return WhitespacePattern().Replace(input, " ");
}
Migration from Runtime Regex
Before (Runtime)
// Anti-pattern: Runtime compilation
public class Validator
{
private static readonly Regex _emailRegex =
new(@"^[\w\.-]+@[\w\.-]+\.\w+$", RegexOptions.Compiled);
public bool IsValid(string email)
{
return _emailRegex.IsMatch(email);
}
}
After (Source Generator)
// Best practice: Compile-time generation
public partial class Validator
{
[GeneratedRegex(@"^[\w\.-]+@[\w\.-]+\.\w+$")]
private static partial Regex EmailPattern();
public bool IsValid(string email)
{
return EmailPattern().IsMatch(email);
}
}
RegexOptions
// Multiple options
[GeneratedRegex(@"pattern", RegexOptions.IgnoreCase | RegexOptions.Multiline)]
private static partial Regex MultiOptionPattern();
// With timeout (for untrusted input)
[GeneratedRegex(@"complex.*pattern", RegexOptions.None, matchTimeoutMilliseconds: 1000)]
private static partial Regex SafePattern();
WPF Validation Example
public partial class FormViewModel : ObservableValidator
{
[GeneratedRegex(@"^[\w\.-]+@[\w\.-]+\.\w+$", RegexOptions.IgnoreCase)]
private static partial Regex EmailPattern();
[GeneratedRegex(@"^\d{3}-\d{3,4}-\d{4}$")]
private static partial Regex PhonePattern();
[CustomValidation(typeof(FormViewModel), nameof(ValidateEmail))]
[ObservableProperty] private string _email = string.Empty;
[CustomValidation(typeof(FormViewModel), nameof(ValidatePhone))]
[ObservableProperty] private string _phone = string.Empty;
public static ValidationResult? ValidateEmail(string email, ValidationContext context)
{
if (string.IsNullOrEmpty(email))
return new ValidationResult("Email is required");
if (!EmailPattern().IsMatch(email))
return new ValidationResult("Invalid email format");
return ValidationResult.Success;
}
public static ValidationResult? ValidatePhone(string phone, ValidationContext context)
{
if (string.IsNullOrEmpty(phone))
return ValidationResult.Success; // Optional field
if (!PhonePattern().IsMatch(phone))
return new ValidationResult("Format: 000-0000-0000");
return ValidationResult.Success;
}
}
GlobalUsings.cs
global using System.Text.RegularExpressions;
Checklist
- Class is marked as
partial - Method is
static partialreturningRegex - Pattern string is valid regex
- Target framework is .NET 7+
- Consider
RegexOptionsfor case sensitivity - Add timeout for untrusted input patterns
Weekly Installs
3
Repository
christian289/do…audecodeGitHub Stars
16
First Seen
Feb 28, 2026
Security Audits
Installed on
opencode3
gemini-cli3
codebuddy3
github-copilot3
codex3
kimi-cli3