ilario-pierbattista/reverse-regex
Generate example strings from regular expressions in PHP—useful for test data for forms, databases, and regex validation. Includes lexer/parser and random generators, supports literals, groups, classes, ranges, and quantifiers (with some Unicode/PCRE limits).
Installation:
composer require ilario-pierbattista/reverse-regex
Ensure your project uses PHP 8.1+ (hard requirement).
Basic Usage:
use ReverseRegex\Lexer;
use ReverseRegex\Random\SimpleRandom;
use ReverseRegex\Parser;
use ReverseRegex\Generator\Scope;
$lexer = new Lexer('[A-Z]{5}-\d{4}'); // Example: "ABCDE-1234"
$random = new SimpleRandom(12345); // Seed for reproducibility
$parser = new Parser($lexer, new Scope(), new Scope());
$result = $parser->parse()->getResult()->generate('', $random);
echo $result; // Outputs: "G7HJK-9012" (varies with seed)
First Use Case:
Generate test data for Laravel validation rules. For example, if your User model validates license_number as /^[A-Z]{3}-\d{4}$/, use:
$licenseRegex = new Lexer('^[A-Z]{3}-\\d{4}$');
$licenseData = $parser->parse()->getResult()->generate('', $random);
SimpleRandom Class: For seeded reproducibility in tests.Define Regex:
Escape meta-characters (e.g., \d for digits, \[ for literal [). Use supported quantifiers ({n}, {n,m}).
$regex = new Lexer('\\d{3}-\\d{2}-\\d{4}'); // SSN-like format
Configure Generator:
SimpleRandom for reproducibility (seed with a constant).*, +), ensure SimpleRandom is updated (fixed in v0.6.0).Generate Data:
$parser = new Parser($regex, new Scope(), new Scope());
$result = $parser->parse()->getResult()->generate('', $random);
Integrate with Laravel:
DatabaseFactory to generate regex-compliant data:
use ReverseRegex\Lexer;
use ReverseRegex\Random\SimpleRandom;
public function definition()
{
$lexer = new Lexer('[A-Za-z0-9]{10}');
$random = new SimpleRandom(42);
return [
'token' => (new Parser($lexer, new Scope(), new Scope()))
->parse()
->getResult()
->generate('', $random),
];
}
beforeEach(function () {
$this->testData = (new Parser(
new Lexer('\\d{4}-\\d{2}-\\d{2}'),
new Scope(),
new Scope()
))->parse()->getResult()->generate('', new SimpleRandom(123));
});
Unicode Support: Generate emojis or non-ASCII text:
$lexer = new Lexer('\\X{1F600}-\\X{1F64F}'); // Emoji range
Nested Groups: Handle complex patterns like:
$lexer = new Lexer('([A-Za-z]{3}-)?\\d{5}'); // Optional prefix
Custom Randomness:
Extend SimpleRandom for domain-specific logic (e.g., biased distributions):
class BiasedRandom extends SimpleRandom {
public function generate(int $min, int $max): int {
// Custom logic (e.g., 70% chance for min value)
return $min === 0 ? 0 : parent::generate($min, $max);
}
}
Batch Generation: Loop to generate multiple values:
$results = [];
for ($i = 0; $i < 10; $i++) {
$results[] = $parser->parse()->getResult()->generate('', $random);
}
Integration with Laravel Testing: Create a helper trait for reusable generation:
trait GeneratesRegexData {
protected function generate(string $regex, int $seed = 12345): string {
$lexer = new Lexer($regex);
$random = new SimpleRandom($seed);
return (new Parser($lexer, new Scope(), new Scope()))
->parse()
->getResult()
->generate('', $random);
}
}
Use in tests:
use GeneratesRegexData;
it('validates license numbers', function () {
$license = $this->generate('^[A-Z]{3}-\\d{4}$');
// Assertions...
});
Unsupported Regex Features:
\p{L} (Unicode properties), lookarounds, backreferences, or conditional regex.Quantifier Behavior:
* and + can generate extremely long strings (up to PHP_INT_MAX). Use explicit bounds (e.g., {0,10}) for safety.SimpleRandom to handle unbounded quantifiers (resolved in v0.6.0).Meta-Character Escaping:
\\d for literal d). The package expects regex syntax, not string literals.[, use \\\[.Unicode Limitations:
\p{...} (Unicode properties) are not supported. Use \X{####} for specific codepoints.[\X{0041}-\X{005A}] for [A-Z]).PHP 8.1+ Requirement:
Seeding Issues:
SimpleRandom uses a fixed seed for reproducibility. If tests fail intermittently, ensure the seed is consistent across runs.Performance:
Validate Regex First: Test your regex in a tool like Regex101 to ensure it matches expected patterns before using the package.
Check Parser Output:
Use var_dump($parser->parse()) to inspect the parsed structure if generation fails.
Handle Exceptions: Wrap generation in a try-catch for unsupported syntax:
try {
$result = $parser->parse()->getResult()->generate('', $random);
} catch (\Exception $e) {
// Fallback to default data or rethrow
}
CI/CD Integration: Add Composer scripts to enforce code quality (as in the package):
{
"scripts": {
"test:regex": "vendor/bin/phpunit --filter RegexTest",
"cs-check": "vendor/bin/php-cs-fixer fix --dry-run"
}
}
Custom Random Generators:
Extend SimpleRandom to implement domain-specific logic (e.g., biased distributions, custom probability maps).
Post-Processing:
Chain generation with Laravel’s Str::of() or Str::random() for additional transformations:
$generated = $parser->parse()->getResult()->generate('', $random);
$processed = Str::upper($generated); // Example: Force uppercase
Laravel Service Provider: Bind the package to the container for global access:
$this->app->bind(GeneratorInterface::class, function ($app) {
return (new Parser(
new Lexer('[A-Za-z0-9]{10}'),
new Scope(),
new Scope()
))->parse()->getResult();
});
Testing Utilities: Create a PestPHP plugin or PHPUnit extension to auto-generate regex data in test methods:
// In Pest.php
Pest::
How can I help you explore Laravel packages today?