Rejigs 1.3.0
dotnet add package Rejigs --version 1.3.0
NuGet\Install-Package Rejigs -Version 1.3.0
<PackageReference Include="Rejigs" Version="1.3.0" />
<PackageVersion Include="Rejigs" Version="1.3.0" />
<PackageReference Include="Rejigs" />
paket add Rejigs --version 1.3.0
#r "nuget: Rejigs, 1.3.0"
#:package Rejigs@1.3.0
#addin nuget:?package=Rejigs&version=1.3.0
#tool nuget:?package=Rejigs&version=1.3.0
Rejigs
A fluent, intuitive, and thread-safe builder for regular expressions in C#
Rejigs makes creating complex regular expressions simple and readable by providing a fluent API that builds patterns step by step. Built with immutability at its core, Rejigs is inherently thread-safe and follows functional programming principles. No more cryptic regex syntax — write patterns that are easy to understand, maintain, and safely use across multiple threads.
Key Features
- Fluent API — Build complex regex patterns with readable, chainable methods
- Thread-Safe — Immutable design ensures safe usage across multiple threads
- Immutable — Each operation returns a new instance, preventing side effects
- Performant — No locking overhead thanks to immutable architecture
- Well-Tested — 370+ comprehensive tests ensuring reliability
Getting Started
Installation
Install Rejigs via NuGet Package Manager:
dotnet add package Rejigs
Or via Package Manager Console:
Install-Package Rejigs
Basic Usage
using Rejigs;
// Simple text matching
var regex = Rejigs.Create()
.AtStart()
.Text("hello")
.AtEnd()
.Build();
Console.WriteLine(regex.IsMatch("hello")); // True
Console.WriteLine(regex.IsMatch("hello world")); // False
Real-World Examples
Email Validation
var emailRegex = Rejigs.Create()
.AtStart()
.OneOrMore(r => r.AnyLetterOrDigit().Or().AnyOf(".-_")) // Local part
.Text("@")
.OneOrMore(r => r.AnyLetterOrDigit().Or().AnyOf(".-")) // Domain
.Text(".")
.AnyInRange('a', 'z') // Top-level domain (2-6 letters)
.Between(2, 6)
.AtEnd()
.IgnoreCase() // Case-insensitive matching
.Build();
Console.WriteLine(emailRegex.IsMatch("user@example.com")); // True
Console.WriteLine(emailRegex.IsMatch("invalid-email")); // False
Validation
Rejigs provides built-in validation methods to check input strings against patterns.
Validate (throws on failure)
var pattern = Rejigs.Create().AtStart().OneOrMore(r => r.AnyDigit()).AtEnd();
pattern.Validate("12345"); // Returns true
pattern.Validate("abc"); // Throws RejigsValidationException
TryValidate (returns a result object)
For scenarios where you prefer not to use exceptions for control flow, use TryValidate. It returns a RejigsValidationResult with IsValid and ErrorMessage properties:
var pattern = Rejigs.Create().AtStart().OneOrMore(r => r.AnyDigit()).AtEnd();
var result = pattern.TryValidate("12345");
Console.WriteLine(result.IsValid); // True
Console.WriteLine(result.ErrorMessage); // null
var failed = pattern.TryValidate("abc");
Console.WriteLine(failed.IsValid); // False
Console.WriteLine(failed.ErrorMessage); // "Input 'abc' does not match the required pattern"
Thread Safety & Immutability
Rejigs is built with immutability at its core, making it inherently thread-safe without any performance overhead from locking mechanisms.
How It Works
Every method call returns a new instance rather than modifying the existing one:
var basePattern = Rejigs.Create().Text("hello");
var pattern1 = basePattern.Text(" world"); // New instance
var pattern2 = basePattern.Text(" there"); // Another new instance
// basePattern remains unchanged: "hello"
// pattern1 contains: "hello world"
// pattern2 contains: "hello there"
Safe Concurrent Usage
You can safely share Rejigs builders across multiple threads:
// Safe to use in multiple threads simultaneously
var sharedBuilder = Rejigs.Create()
.AtStart()
.OneOrMore(r => r.AnyDigit());
// Thread 1
var phonePattern = sharedBuilder.Text("-").Exactly(3, r => r.AnyDigit()).Build();
// Thread 2 (concurrent with Thread 1)
var idPattern = sharedBuilder.AtEnd().Build();
// No race conditions or shared state issues!
Performance Benefits
- No locking overhead — Unlike mutable builders, no synchronization primitives needed
- Predictable performance — Operations are always O(1) for state creation
- Memory efficient — Only creates new instances when needed
- Garbage collector friendly — Short-lived intermediate objects
Tips and Best Practices
- Use descriptive variable names —
var emailRegex = ...instead ofvar regex = ... - Break complex patterns into smaller parts — Use variables to store intermediate builders
- Add comments — Explain what each part of your regex does
- Test thoroughly — Use unit tests to verify your patterns work correctly
- Use
AtStart()andAtEnd()— For exact matches, always anchor your patterns - Leverage immutability — Store base patterns and derive variations safely
- Thread-safe by design — Share builders across threads without locks
- Cache compiled regexes — Store the final
Build()result for repeated use - Prefer
TryValidateoverValidate— Use the non-throwing variant when validation failure is expected
Multi-Threading Example
// Create a base pattern (safe to share)
var baseValidation = Rejigs.Create().AtStart().OneOrMore(r => r.AnyLetterOrDigit());
// Multiple threads can safely extend the pattern
Task.Run(() => {
var emailPattern = baseValidation.Text("@").OneOrMore(r => r.AnyLetterOrDigit()).Build();
// Use emailPattern...
});
Task.Run(() => {
var usernamePattern = baseValidation.AtEnd().Build();
// Use usernamePattern...
});
// No synchronization needed!
Documentation
For detailed documentation, examples, and API reference, visit the Rejigs Documentation.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to raise an issue or a PR.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.