php-standard-library/regex
Type-safe regex for PHP with typed capture groups and predictable error handling. Build expressions with confidence, get structured match results, and avoid silent failures common in preg_* functions. Part of PHP Standard Library.
Installation: Add the package via Composer in your Laravel project:
composer require php-standard-library/regex
Ensure your composer.json includes "php": "^8.0" (or higher) as a requirement.
First Use Case:
Replace a basic preg_match validation with the package’s type-safe alternative. For example:
use PHPStandardLibrary\Regex;
// Traditional approach
if (preg_match('/^[A-Za-z0-9]+$/', $input)) {
// Process valid input
}
// With the package
if (Regex::test('/^[A-Za-z0-9]+$/', $input)) {
// Process valid input
}
Key Entry Points:
Regex::test(string $pattern, string $subject): Equivalent to preg_match but returns a bool.Regex::extract(string $pattern, string $subject): Returns an array of typed capture groups (e.g., ['group1' => string, 'group2' => int]).Regex::replace(string $pattern, string $replacement, string $subject): Type-safe preg_replace.Where to Look First:
src/Regex.php in the package source to understand the core methods and their return types.Validator or FormRequest classes to integrate regex logic into validation rules.Use the package to create reusable validation rules in Laravel. Example:
use PHPStandardLibrary\Regex;
use Illuminate\Validation\Rule;
class RegexRule extends Rule {
protected $pattern;
public function __construct(string $pattern) {
$this->pattern = $pattern;
}
public function passes($attribute, $value) {
return Regex::test($this->pattern, $value);
}
}
// Usage in FormRequest
public function rules() {
return [
'username' => ['required', new RegexRule('/^[A-Za-z0-9_]{4,20}$/')],
];
}
Extract and type-cast capture groups from strings (e.g., parsing logs, CSV, or API responses):
$logLine = "2023-10-01 [ERROR] User 123 failed login";
$matches = Regex::extract(
'/(\d{4}-\d{2}-\d{2}) \[([A-Z]+)\] User (\d+) (.+)/',
$logLine
);
// $matches is typed as:
// [
// 'date' => '2023-10-01',
// 'level' => 'ERROR',
// 'userId' => '123',
// 'message' => 'failed login'
// ]
Replace patterns with type safety (e.g., sanitizing user input or normalizing text):
$sanitized = Regex::replace(
'/[^A-Za-z0-9\s]/', // Pattern
'-', // Replacement
$userInput // Subject
);
Extend Laravel’s Collection to add regex methods:
use Illuminate\Support\Collection;
Collection::macro('extractRegex', function ($pattern) {
return $this->map(function ($item) use ($pattern) {
return Regex::extract($pattern, $item);
});
});
// Usage
$logs = collect($logLines)->extractRegex('/\d{4}-\d{2}-\d{2}/');
Create custom Blade directives for client-side-like regex operations:
use Illuminate\Support\Facades\Blade;
Blade::directive('regex', function ($expression) {
return "<?php echo PHPStandardLibrary\Regex::test({$expression[0]}, {$expression[1]}); ?>";
});
// Usage in Blade
@regex('/^[A-Za-z]+$/', $username)
<p>Username is valid!</p>
@else
<p>Invalid username.</p>
@endregex
config/regex.php) for reusability.
return [
'username' => '/^[A-Za-z0-9_]{4,20}$/',
'email' => '/^[^\s@]+@[^\s@]+\.[^\s@]+$/',
];
RegexRule in FormRequest or Validator.
$validator = Validator::make($request->all(), [
'username' => ['required', new RegexRule(config('regex.username'))],
]);
Regex::extract() to parse structured text (e.g., logs, CSV).
$data = Regex::extract('/(\d+),([^,]+),(\d+\.\d+)/', $csvLine);
$id = (int) $data['group1']; // Automatically cast to int if pattern enforces it
extractRegex macro to parse batches of data.
$parsedData = $collection->extractRegex('/pattern/');
public function testUsernameValidation() {
$this->assertTrue(Regex::test('/^[A-Za-z0-9_]{4,20}$/', 'valid_user'));
$this->assertFalse(Regex::test('/^[A-Za-z0-9_]{4,20}$/', 'invalid user!'));
}
public function testFormRequestValidation() {
$response = $this->post('/register', ['username' => 'bad@user']);
$response->assertSessionHasErrors('username');
}
Leverage Laravel’s Service Container: Bind the package to the container for dependency injection:
$this->app->singleton('regex', function () {
return new \PHPStandardLibrary\Regex();
});
Then inject it into classes:
public function __construct(private Regex $regex) {}
Custom Error Handling: Extend the package’s error handling to integrate with Laravel’s exception system:
try {
Regex::extract('/invalid_pattern/', $subject);
} catch (\PHPStandardLibrary\Regex\RegexException $e) {
throw new \Illuminate\Validation\ValidationException($e->getMessage());
}
Performance Optimization:
static private $compiledPatterns = [];
public static function test(string $pattern, string $subject) {
if (!isset(self::$compiledPatterns[$pattern])) {
self::$compiledPatterns[$pattern] = preg_compile($pattern);
}
return preg_match(self::$compiledPatterns[$pattern], $subject);
}
preg_* for critical paths using Laravel’s Benchmark facade.Documentation:
/**
* Validates a username using a predefined regex pattern.
*
* @param string $username The username to validate.
* @return bool True if the username matches /^[A-Za-z0-9_]{4,20}$/.
*/
public function validateUsername(string $username): bool {
return Regex::test('/^[A-Za-z0-9_]{4,20}$/', $username);
}
Team Onboarding:
PCRE Limitations:
preg_* or consider a more specialized library.How can I help you explore Laravel packages today?