Basic Usage
This guide covers all the core operations available in Relex for working with regular expressions.
Matching
Section titled “Matching”Simple Match
Section titled “Simple Match”Use match() to find the first occurrence of a pattern:
use Cline\Relex\Relex;
$match = Relex::match('/\d+/', 'Order #12345 placed');
$match->hasMatch(); // true$match->result(); // "12345"Testing for Matches
Section titled “Testing for Matches”Use test() when you only need a boolean result:
// More efficient than match() when you don't need the resultif (Relex::test('/^[a-z]+$/', $username)) { // Valid username}Accessing Groups
Section titled “Accessing Groups”Capture groups can be accessed by index or name:
$match = Relex::match('/(\d{4})-(\d{2})-(\d{2})/', '2024-12-08');
// By index (0 is full match)$match->group(0); // "2024-12-08"$match->group(1); // "2024"$match->group(2); // "12"$match->group(3); // "08"
// All groups$match->groups(); // [0 => "2024-12-08", 1 => "2024", 2 => "12", 3 => "08"]Named Captures
Section titled “Named Captures”Named groups provide more readable code:
$match = Relex::match( '/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/', '2024-12-08');
$match->group('year'); // "2024"$match->group('month'); // "12"$match->group('day'); // "08"
// Get all named groups$match->namedGroups(); // ['year' => '2024', 'month' => '12', 'day' => '08']Match with Offsets
Section titled “Match with Offsets”Get the byte position of matches:
$match = Relex::matchWithOffsets('/\d+/', 'abc123def');
$match->result(); // "123"$match->offset(); // 3Match All
Section titled “Match All”Find all occurrences of a pattern:
$matches = Relex::matchAll('/\d+/', 'a1 b22 c333');
$matches->count(); // 3$matches->results(); // ["1", "22", "333"]
// Access individual matches$matches->first()->result(); // "1"$matches->last()->result(); // "333"$matches->get(1)->result(); // "22"Iterating Matches
Section titled “Iterating Matches”$matches = Relex::matchAll('/\w+/', 'hello world');
foreach ($matches as $match) { echo $match->result() . "\n";}
// Or use each()$matches->each(function ($match, $index) { echo "{$index}: {$match->result()}\n";});Replacing
Section titled “Replacing”Simple Replacement
Section titled “Simple Replacement”$result = Relex::replace('/\d+/', 'X', 'a1 b2 c3');$result->result(); // "aX bX cX"$result->count(); // 3 (replacements made)Callback Replacement
Section titled “Callback Replacement”Transform matches using a callback:
$result = Relex::replace('/\d+/', function ($match) { return $match->result() * 2;}, 'a1 b2 c3');
$result->result(); // "a2 b4 c6"The callback receives a MatchResult object with full access to groups:
$result = Relex::replace( '/(?<word>\w+)/', fn($m) => strtoupper($m->group('word')), 'hello world');
$result->result(); // "HELLO WORLD"Replace First Only
Section titled “Replace First Only”$result = Relex::replaceFirst('/\d+/', 'X', 'a1 b2 c3');$result->result(); // "aX b2 c3"Multiple Patterns
Section titled “Multiple Patterns”Replace multiple patterns at once:
$result = Relex::replace( ['/\d+/', '/[a-z]+/'], ['#', '*'], 'a1 b2');
$result->result(); // "* *"Splitting
Section titled “Splitting”Basic Split
Section titled “Basic Split”$split = Relex::split('/\s+/', 'hello world foo');$split->results(); // ["hello", "world", "foo"]$split->count(); // 3Split with Limit
Section titled “Split with Limit”$split = Relex::split('/\s+/', 'a b c d e', 3);$split->results(); // ["a", "b", "c d e"]Keep Delimiters
Section titled “Keep Delimiters”Include the matched delimiters in results:
$split = Relex::splitWithDelimiters('/(\s+)/', 'a b c');$split->results(); // ["a", " ", "b", " ", "c"]Split Operations
Section titled “Split Operations”$split = Relex::split('/,/', 'a,b,c,d,e');
$split->first(); // "a"$split->last(); // "e"$split->get(2); // "c"
// Take and skip$split->take(2)->results(); // ["a", "b"]$split->skip(2)->results(); // ["c", "d", "e"]
// Filter$split->filter(fn($s) => strlen($s) > 0)->results();
// Join back$split->join('-'); // "a-b-c-d-e"Utility Methods
Section titled “Utility Methods”Escape Special Characters
Section titled “Escape Special Characters”Make strings safe for literal matching:
$escaped = Relex::escape('user.name+tag@example.com');// "user\.name\+tag@example\.com"
$pattern = '/' . Relex::escape($userInput) . '/';Validate Patterns
Section titled “Validate Patterns”Check if a pattern is syntactically correct:
Relex::isValid('/\d+/'); // trueRelex::isValid('/[invalid'); // false
// Throw on invalidRelex::validate('/[invalid'); // throws PatternCompilationExceptionCount Matches
Section titled “Count Matches”$count = Relex::count('/\d/', 'a1b2c3');// 3Extract All Matches
Section titled “Extract All Matches”Get matches as a simple array:
$numbers = Relex::extract('/\d+/', 'a1 b22 c333');// ["1", "22", "333"]Pluck Named Group
Section titled “Pluck Named Group”Extract a specific group from all matches:
$dates = 'Meeting on 2024-01-15, follow-up 2024-02-20';$years = Relex::pluck('/(?<year>\d{4})-\d{2}-\d{2}/', $dates, 'year');// ["2024", "2024"]Filter Arrays
Section titled “Filter Arrays”Keep only strings matching a pattern:
$emails = ['user@example.com', 'invalid', 'other@test.org'];$valid = Relex::filter('/^\w+@\w+\.\w+$/', $emails);// ["user@example.com", "other@test.org"]Reject Arrays
Section titled “Reject Arrays”Remove strings matching a pattern:
$items = ['apple', 'banana123', 'cherry'];$clean = Relex::reject('/\d/', $items);// ["apple", "cherry"]Find First Match
Section titled “Find First Match”Get the first array element matching a pattern:
$files = ['readme.txt', 'image.png', 'data.json'];$image = Relex::first('/\.png$/', $files);// "image.png"Create Literal Alternation
Section titled “Create Literal Alternation”Match any of several literal strings:
$pattern = Relex::any(['foo', 'bar', 'baz']);Relex::test($pattern, 'foobar'); // trueRelex::test($pattern, 'qux'); // falseChaining Operations
Section titled “Chaining Operations”Value objects support fluent chaining:
$result = Relex::matchAll('/\d+/', 'a1 b22 c333 d4444') ->filter(fn($m) => strlen($m->result()) > 1) ->take(2) ->map(fn($m) => (int) $m->result());
// [22, 333]$sum = Relex::matchAll('/\d+/', 'a1 b2 c3') ->reduce(fn($carry, $m) => $carry + (int) $m->result(), 0);
// 6