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+ (Laravel 10+).
Basic Usage:
use ReverseRegex\Lexer;
use ReverseRegex\Random\SimpleRandom;
use ReverseRegex\Parser;
use ReverseRegex\Generator\Scope;
$lexer = new Lexer('[A-Z]{5}[0-9]{4}'); // Example: "ABCDE1234"
$random = new SimpleRandom(12345); // Seed for reproducibility
$parser = new Parser($lexer, new Scope(), new Scope());
$result = $parser->parse()->getResult()->generate('', $random);
echo $result; // Outputs: e.g., "XK9QJ7421"
First Use Case:
Generate test data for Laravel validation rules (e.g., regex:/^[A-Z]{5}[0-9]{4}$/):
$regex = '[A-Z]{5}[0-9]{4}';
$testData = collect(range(1, 10))->map(fn() => generateString($regex))->toArray();
ausphone.php, auspostcode.php) for Laravel-relevant patterns.Service Provider: Register a facade or service container binding for reusable generation:
// app/Providers/ReverseRegexServiceProvider.php
public function register()
{
$this->app->singleton('regex.generator', function () {
return new class {
public function generate(string $regex, int $seed = null): string {
$lexer = new Lexer($regex);
$random = new SimpleRandom($seed ?? random_int(0, PHP_INT_MAX));
return (new Parser($lexer, new Scope(), new Scope()))
->parse()
->getResult()
->generate('', $random);
}
};
});
}
PestPHP Helper:
Add a helper to tests/Pest.php:
uses(Tests\TestCase::class)->in('*');
uses(function () {
$this->generateRegexString = function (string $regex, int $seed = null) {
return app('regex.generator')->generate($regex, $seed);
};
});
Factory Macro: Extend Laravel factories for seeded test data:
// Database/Factories/UserFactory.php
public function configure(): static
{
return $this->afterCreating(function (User $user) {
$user->api_token = $this->generateRegexString('[A-Za-z0-9]{40}');
});
}
Define Regex:
Align with Laravel validation rules (e.g., regex:/^(?=.*[A-Z])(?=.*\d).{8,}$/ for passwords).
Generate Data:
$password = $this->generateRegexString('^(?=.*[A-Z])(?=.*\d).{8,}$');
Reuse in Tests:
it('validates complex passwords', function () {
$password = $this->generateRegexString('^(?=.*[A-Z])(?=.*\d).{8,}$');
$this->assertTrue(Str::is($password, '/^(?=.*[A-Z])(?=.*\d).{8,}$/'));
});
Use a fixed seed in CI/CD to ensure consistent test data:
$seededData = $this->generateRegexString('[A-Z]{3}[0-9]{4}', 42);
Generate arrays of test data for bulk operations:
$testEmails = collect(range(1, 50))->map(fn($i) =>
$this->generateRegexString('[a-z]+@example\.com')
)->toArray();
Test validation rules dynamically:
$validator = Validator::make(['code' => $this->generateRegexString('[A-Z]{5}')], [
'code' => 'regex:/^[A-Z]{5}$/',
]);
$validator->validate(); // Passes
Generate locale-specific data (e.g., emojis, non-ASCII):
$emoji = $this->generateRegexString('\X{1F600}'); // 😀
$hexString = $this->generateRegexString('\x41-\x5A'); // Random uppercase letter
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);
}
}
Wrap generation in a try-catch for unsupported regex:
try {
$data = $this->generateRegexString('\p{L}'); // Unsupported
} catch (\Exception $e) {
$this->fail('Unsupported regex: ' . $e->getMessage());
}
Use generateRegexString in data providers:
$dataProvider = [
'valid' => [$this->generateRegexString('[A-Z]{3}')],
'invalid' => [$this->generateRegexString('[a-z]{3}')],
];
Seed tables with regex-compliant data:
// database/seeders/UsersTableSeeder.php
User::factory()->count(100)->create()->each(function ($user) {
$user->update(['license_key' => $this->generateRegexString('[A-F0-9]{16}')]);
});
Generate realistic API payloads:
$payload = [
'token' => $this->generateRegexString('[A-Za-z0-9]{64}'),
'metadata' => json_encode([
'id' => $this->generateRegexString('[0-9]{10}'),
]),
];
Test migrations with edge-case data:
$maxLengthString = $this->generateRegexString('[a-z]{255}');
Schema::create('test_table', function (Blueprint $table) {
$table->string('field', 255)->unique();
});
Unsupported Regex Features:
\p{L} (Unicode properties), lookarounds, backreferences.Unbounded Quantifiers (*, +):
PHP_INT_MAX).{0,10}) or limit with SimpleRandom overrides.Escaping Meta-Characters:
., *) in the input string.preg_quote() for dynamic regex strings:
$dynamicRegex = preg_quote($userInput, '/') . '[0-9]{4}';
Unicode Limitations:
\X{####} requires valid Unicode codepoints; invalid ranges throw errors.preg_match('/^\X{####}$/', $codepoint).Performance with Complex Regex:
{1,1000}) slow generation.How can I help you explore Laravel packages today?