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-Za-z0-9]{10}');
$generator = new SimpleRandom(12345); // Seed for reproducibility
$parser = new Parser($lexer, new Scope(), new Scope());
$result = $parser->parse()->getResult()->generate('', $generator);
// Output: e.g., "aB3dE7fG9h"
First Use Case:
Generate test data for Laravel validation rules. For example, if your User model validates phone_number with regex /^04\d{8}$/, use:
$phoneRegex = '04\d{8}';
$phoneNumber = (new Parser(new Lexer($phoneRegex), new Scope(), new Scope()))
->parse()
->getResult()
->generate('', new SimpleRandom());
// Output: e.g., "0412345678"
ausphone.php, auspostcode.php) for real-world Laravel use cases.Define Regex:
Store validation regexes in a config file (e.g., config/test_data.php) or as constants:
// config/test_data.php
return [
'phone' => '04\d{8}',
'postcode' => '\d{4}',
'username' => '[a-z0-9_]{8,20}',
];
Create a Test Helper: Wrap the package in a Laravel service or helper:
// app/Helpers/RegexGenerator.php
namespace App\Helpers;
use ReverseRegex\Lexer;
use ReverseRegex\Parser;
use ReverseRegex\Generator\Scope;
use ReverseRegex\Random\SimpleRandom;
class RegexGenerator
{
public static function generate(string $regex, int $seed = null): string
{
$lexer = new Lexer($regex);
$generator = new SimpleRandom($seed ?? random_int(0, PHP_INT_MAX));
return (new Parser($lexer, new Scope(), new Scope()))
->parse()
->getResult()
->generate('', $generator);
}
}
Integrate with Laravel Testing:
use App\Helpers\RegexGenerator;
test('phone number validation', function () {
$phone = RegexGenerator::generate('04\d{8}');
$this->assertMatchesRegularExpression('/^04\d{8}$/', $phone);
});
use App\Helpers\RegexGenerator;
public function testPostcodeValidation()
{
$postcode = RegexGenerator::generate('\d{4}');
$this->assertMatchesRegularExpression('/^\d{4}$/', $postcode);
}
Database Seeding:
Use in DatabaseSeeder or model factories:
// database/seeders/DatabaseSeeder.php
public function run()
{
User::factory()->count(10)->create()->each(function ($user) {
$user->phone_number = RegexGenerator::generate('04\d{8}');
$user->save();
});
}
Seeded Randomness: Use a fixed seed for reproducible tests:
$seededGenerator = new SimpleRandom(42);
$result = $parser->parse()->getResult()->generate('', $seededGenerator);
Unicode Support: Generate emojis or special characters:
$emojiRegex = '\X{1F600}-\X{1F64F}'; // Unicode range for smiling faces
$emoji = RegexGenerator::generate($emojiRegex);
Complex Regex: Handle nested groups and alternations:
$complexRegex = '(abc|def){3}'; // Generates "abcabcabc" or "defdefdef"
$output = RegexGenerator::generate($complexRegex);
Integration with Faker: Combine with Faker for hybrid test data:
use Faker\Factory as Faker;
$faker = Faker::create();
$email = $faker->unique()->email;
$password = RegexGenerator::generate('[a-zA-Z0-9]{12}');
Custom Random Generators:
Extend SimpleRandom for domain-specific logic:
class DomainRandom extends SimpleRandom
{
protected function generateCharacter(): string
{
// Custom logic for business-specific rules
return parent::generateCharacter();
}
}
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 ranges (e.g., {1,10}) for control.Escaping Meta-Characters:
\., \*) before passing to Lexer.preg_quote() for dynamic regexes:
$safeRegex = preg_quote($userInput, '/');
PHP 8.1+ Requirement:
Unicode Limitations:
\p{...} (Unicode properties) are not supported. Use \X{####} for codepoints.\xFF).Performance with Large Quantifiers:
{1,1000} can be slow. Optimize by:
Validate Regex First:
Test your regex with preg_match() before using ReverseRegex:
$regex = '[a-z]{5}';
$testString = 'abcde';
$this->assertTrue(preg_match("/{$regex}/", $testString));
Check Parser Output: Inspect the parsed AST for debugging:
$parsed = $parser->parse();
dump($parsed->getResult()->getStructure());
Handle Edge Cases:
CI/CD Integration:
composer phpstan and composer cs-check in your pipeline to enforce standards.Custom Generators:
Extend SimpleRandom to implement domain-specific logic:
class BusinessRandom extends SimpleRandom
{
protected function generateCharacter(): string
{
// Example: Only allow vowels for certain fields
return $this->randomElement(['a', 'e', 'i', 'o', 'u']);
}
}
Laravel Service Provider: Bind the generator to the container for global access:
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(RegexGenerator::class, function ($app) {
return new RegexGenerator();
});
}
PestPHP Custom Macro: Add a macro to Pest for seamless integration:
// tests/Pest.php
use App\Helpers\RegexGenerator;
Pest::macro('regex', function ($pattern) {
return Regex
How can I help you explore Laravel packages today?