mmtaheridev/reginephp

An expressive PHP library for crafting regular expressions fluently.

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/mmtaheridev/reginephp

v1.0.0 2025-08-26 22:48 UTC

This package is auto-updated.

Last update: 2025-10-26 23:28:56 UTC


README

Regine Logo

An Expressive PHP Library for Crafting Regular Expressions fluently.

Latest Version License: MIT PHP Version Tests

๐Ÿš€ The Problem Regine Solves

Regular expressions are powerful but notoriously difficult to read, write, and maintain. A simple email validation can look like this:

/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/

Can you immediately understand what this does? Probably not. And if you need to modify it in 6 months, good luck!

Regine transforms this cryptic pattern into readable, fluent PHP code:

use Regine\Regine;

$emailPattern = Regine::make()
    ->startOfString()
    ->anyOf('a-zA-Z0-9._%+-')->oneOrMore()
    ->literal('@')
    ->anyOf('a-zA-Z0-9.-')->oneOrMore()
    ->literal('.')
    ->anyOf('a-zA-Z')->between(2, 4)
    ->endOfString()
    ->compile();

Now it reads like English! ๐ŸŽ‰

๐Ÿ—๏ธ Architecture: Component-Decorator Pattern

Regine uses a clean Component-Decorator architecture that separates concerns:

  • ๐Ÿงฉ Components: Actual regex content (literals, character classes, anchors, etc.)
  • ๐ŸŽจ Decorators: Elements that modify/wrap components (groups, quantifiers, lookarounds)

This design provides:

  • โœ… Clean separation of concerns
  • โœ… Simplified grouping logic
  • โœ… Maintainable and extensible codebase
  • โœ… Intuitive API design

๐Ÿ“ฆ Installation

Install Regine via Composer:

composer require mmtaheridev/reginephp

Requirements:

  • PHP 8.3 or higher
  • ext-mbstring (for Unicode support)

๐ŸŽฏ Quick Start

Basic Usage

<?php

require 'vendor/autoload.php';

use Regine\Regine;

// Create a simple pattern
$pattern = Regine::make()
    ->literal('Hello')
    ->whitespace()
    ->literal('World')
    ->compile();

echo $pattern; // Output: /Hello\sWorld/

// Test the pattern
$regine = Regine::make()->literal('Hello')->whitespace()->literal('World');
var_dump($regine->test('Hello World')); // bool(true)

Character Matching

// Match digits
$digitPattern = Regine::make()
    ->startOfString()
    ->digit()->oneOrMore()
    ->endOfString()
    ->compile();
// Output: /^\d+$/

// Match word characters  
$wordPattern = Regine::make()
    ->wordChar()->zeroOrMore()
    ->compile();
// Output: /\w*/

// Match specific characters
$vowelPattern = Regine::make()
    ->anyOf('aeiou')->oneOrMore()
    ->compile();
// Output: /[aeiou]+/

// Advanced character classes
$letterPattern = Regine::make()
    ->letter()->oneOrMore()          // [a-zA-Z]+
    ->compile();

$hexPattern = Regine::make()
    ->range('0', '9')                // [0-9]
    ->range('a', 'f')                // [a-f] 
    ->range('A', 'F')                // [A-F]
    ->oneOrMore()
    ->compile();

Quantifiers

// Various quantifiers
$pattern = Regine::make()
    ->literal('a')->optional()          // a?
    ->literal('b')->zeroOrMore()        // b*
    ->literal('c')->oneOrMore()         // c+
    ->literal('d')->exactly(3)          // d{3}
    ->literal('e')->atLeast(2)          // e{2,}
    ->literal('f')->between(1, 5)       // f{1,5}
    ->compile();
// Output: /a?b*c+d{3}e{2,}f{1,5}/

// Quantifiers with shorthand characters
$complexPattern = Regine::make()
    ->digit()->oneOrMore()              // \d+
    ->whitespace()->zeroOrMore()        // \s*
    ->wordChar()->between(3, 10)        // \w{3,10}
    ->compile();
// Output: /\d+\s*\w{3,10}/

Character Classes and Ranges

// Character classes
$pattern = Regine::make()
    ->anyOf('abc')              // [abc]
    ->noneOf('xyz')             // [^xyz]
    ->range('a', 'z')           // [a-z]
    ->range('A', 'Z')           // [A-Z]
    ->range('0', '9')           // [0-9]
    ->compile();
// Output: /[abc][^xyz][a-z][A-Z][0-9]/

// Advanced character classes
$unicodePattern = Regine::make()
    ->anyOf('ฮฑฮฒฮณ')              // Unicode characters [ฮฑฮฒฮณ]
    ->range('ฮฑ', 'ฯ‰')           // Unicode range [ฮฑ-ฯ‰]
    ->compile();
// Output: /[ฮฑฮฒฮณ][ฮฑ-ฯ‰]/u (note automatic Unicode flag)

// Negated ranges
$notDigitsPattern = Regine::make()
    ->noneOfRange('0', '9')     // [^0-9]
    ->oneOrMore()
    ->compile();
// Output: /[^0-9]+/

Groups and Alternation

// Groups
$pattern = Regine::make()
    ->group(
        Regine::make()->literal('cat')->or('dog')
    )
    ->compile(); // Output: /(cat|dog)/

// Named groups
$pattern = Regine::make()
    ->namedGroup('animal',
        Regine::make()->literal('cat')->or('dog')
    )
    ->compile(); // Output: /(?<animal>cat|dog)/

// Simple alternation
$pattern = Regine::make()
    ->oneOf(['cat', 'dog', 'bird'])
    ->compile(); // Output: /cat|dog|bird/

Advanced Features

// Lookarounds
$lookaheadPattern = Regine::make()
    ->literal('test')
    ->lookahead('ing')                   // (?=ing)
    ->compile();
// Output: /test(?=ing)/

$passwordPattern = Regine::make()
    ->startOfString()
    ->lookahead('.*[a-z]')              // Must contain lowercase
    ->lookahead('.*[A-Z]')              // Must contain uppercase  
    ->lookahead('.*\d')                 // Must contain digit
    ->anyChar()->atLeast(8)             // At least 8 characters
    ->endOfString()
    ->compile();
// Output: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/

// Anchors and boundaries
$wordPattern = Regine::make()
    ->startOfString()
    ->wordBoundary()
    ->literal('hello')
    ->wordBoundary()
    ->endOfString()
    ->compile();
// Output: /^\bhello\b$/

// Flags with method chaining
$flagPattern = Regine::make()
    ->literal('hello')
    ->caseInsensitive()     // i flag
    ->multiline()           // m flag
    ->dotAll()              // s flag
    ->compile();
// Output: /hello/ims

// Short flag methods
$shortFlagPattern = Regine::make()
    ->literal('test')
    ->i()                   // case insensitive
    ->m()                   // multiline
    ->s()                   // dot all
    ->u()                   // unicode
    ->compile();
// Output: /test/imsu

๐Ÿ” Debugging and Testing

Regine provides excellent debugging capabilities:

$regine = Regine::make()
    ->startOfString()
    ->oneOrMore()->digit()
    ->endOfString();

// Get debug information
$debug = $regine->debug();
print_r($debug->toArray());

// Test patterns
var_dump($regine->test('12345'));     // bool(true)
var_dump($regine->test('abc'));       // bool(false)

// Get matches
$matches = $regine->matches('12345');
print_r($matches);

// Get human-readable description
echo $regine->describe();

// Check if pattern is empty
var_dump($regine->isEmpty());         // bool(false)

// Get element count
echo $regine->getElementCount();      // int

๐ŸŽจ Real-World Examples

Email Validation

$emailPattern = Regine::make()
    ->startOfString()
    ->wordChar()->oneOrMore()
    ->anyOf('.-_')->optional()
    ->wordChar()->zeroOrMore()
    ->literal('@')
    ->wordChar()->oneOrMore()
    ->literal('.')
    ->wordChar()->between(2, 4)
    ->endOfString();

// Advanced email validation with lookaheads
$strictEmailPattern = Regine::make()
    ->startOfString()
    ->lookahead('.*@')                  // Must contain @
    ->lookahead('.*\.')                 // Must contain .
    ->negativeLookahead('.*@.*@')       // No double @
    ->wordChar()->oneOrMore()
    ->literal('@')
    ->wordChar()->oneOrMore()
    ->literal('.')
    ->wordChar()->between(2, 4)
    ->endOfString();

// Test both patterns
var_dump($emailPattern->test('user@example.com'));      // true
var_dump($emailPattern->test('invalid.email'));         // false
var_dump($strictEmailPattern->test('user@@example.com')); // false

Phone Number Validation

$phonePattern = Regine::make()
    ->startOfString()
    ->literal('(')->optional()
    ->digit()->exactly(3)
    ->literal(')')->optional()
    ->anyOf(' -')->optional()
    ->digit()->exactly(3)
    ->anyOf(' -')
    ->digit()->exactly(4)
    ->endOfString();

// Alternative using groups for better organization
$groupedPhonePattern = Regine::make()
    ->startOfString()
    ->group(
        Regine::make()
            ->literal('(')
            ->digit()->exactly(3)
            ->literal(')')
    )->optional()
    ->whitespace()->optional()
    ->digit()->exactly(3)
    ->anyOf(' -.')
    ->digit()->exactly(4)
    ->endOfString();

// Test various formats
var_dump($phonePattern->test('(555) 123-4567')); // true
var_dump($phonePattern->test('555-123-4567'));   // true
var_dump($phonePattern->test('5551234567'));     // false (needs separators)

URL Validation

$urlPattern = Regine::make()
    ->startOfString()
    ->group(
        Regine::make()->oneOf(['http', 'https'])
    )
    ->literal('://')
    ->anyOf('a-zA-Z0-9.-')->oneOrMore()
    ->literal('.')
    ->anyOf('a-zA-Z')->between(2, 4)
    ->anyOf('/a-zA-Z0-9._~:/?#[]@!$&\'()*+,;=-')->zeroOrMore()
    ->endOfString();

// More flexible URL pattern with optional parts
$flexibleUrlPattern = Regine::make()
    ->startOfString()
    ->group(
        Regine::make()->oneOf(['http', 'https', 'ftp'])
    )
    ->literal('://')
    ->group(                            // Optional auth
        Regine::make()
            ->wordChar()->oneOrMore()
            ->literal(':')
            ->wordChar()->oneOrMore()
            ->literal('@')
    )->optional()
    ->anyOf('a-zA-Z0-9.-')->oneOrMore() // Domain
    ->group(                            // Optional port
        Regine::make()
            ->literal(':')
            ->range('0', '9')->between(1, 5)
    )->optional()
    ->group(                            // Optional path
        Regine::make()
            ->literal('/')
            ->anyOf('a-zA-Z0-9._~:/?#[]@!$&\'()*+,;=-')->zeroOrMore()
    )->optional()
    ->endOfString();

var_dump($urlPattern->test('https://example.com/path')); // true
var_dump($flexibleUrlPattern->test('https://user:pass@example.com:8080/path')); // true

๐Ÿงช Testing

Regine comes with comprehensive test coverage:

# Run tests
./vendor/bin/pest

# Run tests with coverage
./vendor/bin/pest --coverage

# Run static analysis
./vendor/bin/phpstan analyse

# Format code
./vendor/bin/duster fix

๐ŸŒŸ Future Roadmap

We're building something revolutionary for the PHP ecosystem. Here's what's coming:

๐ŸŽฏ Comprehensive Pattern Library

  • Hundreds of Pre-built Patterns: Email, phone, URL, credit card, social security, and much more
  • Zero-Regex Philosophy: Handle 99% of use cases without writing raw regex
  • Domain-Specific Patterns: Financial, geographic, technical, and specialized patterns

๐Ÿš€ Enterprise Features

  • Pattern Composition Tools: Combine and extend patterns effortlessly
  • Performance Optimizations: Sub-millisecond compilation for complex patterns
  • Advanced Debugging: Visual pattern representation and analysis tools
  • International Support: Localized patterns for global applications

๐Ÿ”ง Developer Experience

  • IDE Integration: Full autocompletion and documentation
  • Pattern Validation: Real-time pattern testing and validation
  • Framework Integration: Laravel, Symfony, and other framework integrations

Stay tuned - we're just getting started! ๐Ÿš€

๐Ÿค Contributing

We welcome contributions!.

Development Setup

git clone https://github.com/mmtaheridev/reginephp.git
cd reginephp
composer install
./vendor/bin/pest

๐Ÿ“„ License

Regine is open-sourced software licensed under the MIT license.

๐Ÿ™ Acknowledgments

  • Inspired by Laravel's Eloquent ORM fluent interface design
  • Built with PHP 8.3+ features for modern development
  • Tested with Pest PHP for reliable quality assurance
Made with โค๏ธ by Mohammad Mahdi Taheri

โญ Star this repo if you find it useful! โญ