composer/pcre
Type-safe wrapper around PHP’s preg_* functions. Composer\Pcre\Preg prevents silent PCRE failures, standardizes return types (PREG_UNMATCHED_AS_NULL), and improves static analysis with a PHPStan extension for regex-aware typing.
Install the package via Composer:
composer require composer/pcre
Start by replacing basic preg_match, preg_replace, and preg_split calls with the library’s type-safe equivalents. For example, instead of:
if (preg_match('/foo/', $subject, $matches)) { ... }
Use:
use function Composer\Pcre\PcreFacade\match;
$result = match('/foo/', $subject);
if ($result->success()) {
$matches = $result->groups(); // Returns array with named/captured groups
}
First look at PcreFacade methods (match, replace, split, replaceCallback) — these are the entry points for daily usage.
replace() with ReplaceResult to safely handle failed patterns:
$result = replace('/\d+/', 'X', $text);
if ($result->success()) {
$replaced = $result->text;
} else {
log('PCRE error: ' . $result->error);
}
MatchResult::group('name') or MatchResult->groups() for full structured data.replaceCallback() over preg_replace_callback() for better error handling:
$result = replaceCallback('/\{(.*?)\}/', fn($m) => $variables[$m[1] ?? ''] ?? '', $template);
match() for branching (e.g., route dispatch, config parsing) without try/catch boilerplate.PcreFacade (or its interface) for unit testing; avoid calling global preg_* functions directly.PcreException here — always ensure patterns are validated before use (e.g., via preg_last_error() === PREG_NO_ERROR).u modifier for multibyte strings — it’s not added automatically.MatchResult::groups() returns all groups (including full match at index 0); use MatchResult::group($indexOrName) for targeted access.Pcre::match() directly (non-facade) to avoid static overhead; facade is fine for app-level logic.ReplaceResult::error() gives the raw PCRE error message — parse if needed for user feedback, but never expose directly to end users.Pcre class to add domain-specific helpers (e.g., Pcre::extractEmails()) without violating encapsulation.How can I help you explore Laravel packages today?