PHPackages                             brannow/typed-pattern-engine - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. brannow/typed-pattern-engine

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

brannow/typed-pattern-engine
============================

Human-readable pattern matching engine with type-safe value extraction and bidirectional processing

0.4.0(7mo ago)0422↓50%1MITPHPPHP ^8.1CI failing

Since Sep 22Pushed 5mo agoCompare

[ Source](https://github.com/brannow/typed-pattern-engine)[ Packagist](https://packagist.org/packages/brannow/typed-pattern-engine)[ RSS](/packages/brannow-typed-pattern-engine/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (3)Versions (2)Used By (1)

TypedPatternEngine
==================

[](#typedpatternengine)

Human-readable pattern matching engine with type-safe value extraction and bidirectional processing for PHP 8.1+.

Overview
--------

[](#overview)

TypedPatternEngine provides a Domain Specific Language (DSL) for defining patterns that compile to regular expressions. It extracts typed, validated values from matched strings and supports bidirectional processing (matching input and generating output from values).

**Key Features:**

- Type-safe value extraction with automatic casting
- Constraint validation system
- Optional sections with sophisticated logic
- Bidirectional pattern processing (match ↔ generate)
- Pattern compilation with validation pipeline
- Heuristic analysis for performance optimization

Installation
------------

[](#installation)

```
composer require brannow/typed-pattern-engine
```

**Requirements:** PHP 8.1+

Quick Start
-----------

[](#quick-start)

```
use TypedPatternEngine\TypedPatternEngine;
use TypedPatternEngine\Types\TypeRegistry;

$engine = new TypedPatternEngine(new TypeRegistry());
$compiler = $engine->getPatternCompiler();

// Compile pattern
$pattern = "user/{id:int}/posts/{postId:int}?";
$compiled = $compiler->compile($pattern);

// Match input
$result = $compiled->match("user/123/posts/456");
if ($result) {
    echo $result->get('id');      // 123 (int)
    echo $result->get('postId');  // 456 (int)
}

// Generate output
$output = $compiled->generate(['id' => 123, 'postId' => 456]);
echo $output; // "user/123/posts/456"
```

Core Concepts
-------------

[](#core-concepts)

### Pattern Syntax

[](#pattern-syntax)

Patterns consist of three elements:

- **Literals**: Static text that must match exactly
- **Groups**: Dynamic segments that capture values: `{name:type}`
- **Optional Sections**: Parts that may or may not be present: `(...)`

#### Basic Groups

[](#basic-groups)

```
{groupName:type}                    // Required group
{groupName:type}?                   // Optional group (normalized to subsequence)
{groupName:type(constraints)}       // Group with validation constraints
```

#### Examples

[](#examples)

```
"PAGE{id:int}"                      // Matches: PAGE123
"user-{userId:int}-post-{postId:int}" // Matches: user-5-post-10
"{username:str}@{domain:str}"       // Matches: john@example.com
```

### Types

[](#types)

Built-in types with automatic casting:

TypePatternPHP TypeConstraints`int``\d+``int``min`, `max`, `default``str``[^/]+``string``minLen`, `maxLen`, `contains`, `startsWith`, `endsWith`, `default`### Optional Sections

[](#optional-sections)

Optional sections use subsequence logic where ALL elements must be satisfied if the section matches:

```
"PAGE{id:int}(-{lang:str})"         // Matches: PAGE123 or PAGE123-en
"doc/{id:int}(/edit)"               // Matches: doc/5 or doc/5/edit
```

### Constraints

[](#constraints)

Constraints provide validation without affecting pattern generation:

```
"{id:int(min=1, max=9999)}"         // Integer between 1-9999
"{code:str(minLen=3, maxLen=10)}"   // String length 3-10 characters
"{lang:str(default=en)}?"           // Optional with default value
```

API Reference
-------------

[](#api-reference)

### TypedPatternEngine

[](#typedpatternengine-1)

Main entry point for the pattern engine.

```
$engine = new TypedPatternEngine(TypeRegistry $typeRegistry);
$patternCompiler = $engine->getPatternCompiler();
$heuristicCompiler = $engine->getHeuristicCompiler();
```

### PatternCompiler

[](#patterncompiler)

Compiles patterns into executable objects.

```
$compiled = $compiler->compile(string $pattern): CompiledPattern;
$dehydrated = $compiler->dehydrate(CompiledPattern $pattern): array;
$rehydrated = $compiler->hydrate(array $data): CompiledPattern;
```

### CompiledPattern

[](#compiledpattern)

Executable pattern with matching and generation capabilities.

```
// Matching
$result = $compiled->match(string $input): ?MatchResult;
$regex = $compiled->getRegex(): string;

// Generation
$output = $compiled->generate(array $values): string;
```

### MatchResult

[](#matchresult)

Contains extracted values from successful matches.

```
$value = $result->get(string $key): mixed;
$input = $result->getInput(): string;
$allValues = $result->toArray(): array;
$errors = $result->getErrors(): array;
```

### HeuristicCompiler

[](#heuristiccompiler)

Optimizes pattern matching with pre-filtering.

```
$heuristic = $heuristicCompiler->compile(array $compiledPatterns);
$canMatch = $heuristic->support(string $input): bool;
```

Pattern Examples
----------------

[](#pattern-examples)

### Web Routes

[](#web-routes)

```
// RESTful API
"/api/v{version:int}/{resource:str}/{id:int}?(/edit)"

// Blog URLs
"/blog/{year:int(min=2000)}/{month:int(min=1,max=12)}/{slug:str}"

// Multilingual routes
"/{lang:str}?/page/{pageId:int}(-{slug:str})"
```

### File Paths

[](#file-paths)

```
// Upload paths
"uploads/{year:int}/{month:int}/{filename:str}.{ext:str}"

// Document storage
"docs/{category:str}/{docId:int}(-v{version:int}).pdf"
```

### Identifiers

[](#identifiers)

```
// Order numbers
"ORD-{year:int}-{number:int(min=1,max=999999)}"

// Product SKUs
"{category:str}-{product:int}-{variant:str}?"
```

### Project Structure

[](#project-structure)

```
src/
├── Compiler/           # Pattern compilation and execution
├── Exception/          # Custom exceptions
├── Heuristic/          # Performance optimization
├── Nodes/              # AST node implementations
├── Pattern/            # Pattern parsing and compilation
├── Types/              # Type system and constraints
├── Validation/         # Validation pipeline
└── TypedPatternEngine.php

tests/Unit/             # Comprehensive test suite
documentation/          # Detailed pattern syntax docs

```

Advanced Usage
--------------

[](#advanced-usage)

### Custom Types

[](#custom-types)

Extend the type system by registering custom types:

```
$typeRegistry = new TypeRegistry();
// Custom type registration would be handled via TypeRegistry extension
```

### Error Handling

[](#error-handling)

```
use TypedPatternEngine\Exception\PatternSyntaxException;
use TypedPatternEngine\Exception\PatternValidationException;

try {
    $compiled = $compiler->compile($pattern);
    $result = $compiled->match($input);
} catch (PatternSyntaxException $e) {
    // Invalid pattern syntax
} catch (PatternValidationException $e) {
    // Pattern validation failed
}
```

### Performance Optimization

[](#performance-optimization)

Use heuristic pre-filtering for multiple patterns:

```
$patterns = [
    $compiler->compile("PAGE{id:int}"),
    $compiler->compile("ARTICLE{id:int}"),
    $compiler->compile("USER{name:str}")
];

$heuristic = $engine->getHeuristicCompiler()->compile($patterns);

if ($heuristic->support($input)) {
    // Only test patterns if heuristic suggests possible match
    foreach ($patterns as $pattern) {
        if ($result = $pattern->match($input)) {
            break;
        }
    }
}
```

Documentation
-------------

[](#documentation)

- [Pattern Syntax Reference](documentation/PATTERN_SYNTAX.md) - Complete syntax guide with examples
- [Architecture Overview](documentation/ARCHITECTURE.md) - Technical implementation details

License
-------

[](#license)

MIT License. See LICENSE file for details.

Contributing
------------

[](#contributing)

1. Fork the repository
2. Create feature branch (`git checkout -b feature/new-feature`)
3. Write tests for new functionality
4. Ensure all tests pass (`./docker.sh exec composer test`)
5. Submit pull request

Authors
-------

[](#authors)

**Benjamin Rannow**

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance66

Regular maintenance activity

Popularity16

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

238d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/08917c31f7650fae5b1fadd0b50e1cb992db0249e51ad9817f857af192bf0cae?d=identicon)[brannow](/maintainers/brannow)

---

Top Contributors

[![brannow](https://avatars.githubusercontent.com/u/19426486?v=4)](https://github.com/brannow "brannow (16 commits)")

---

Tags

urlroutingregexDSLparsingpatterntype-safematching

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/brannow-typed-pattern-engine/health.svg)

```
[![Health](https://phpackages.com/badges/brannow-typed-pattern-engine/health.svg)](https://phpackages.com/packages/brannow-typed-pattern-engine)
```

###  Alternatives

[behat/gherkin

Gherkin DSL parser for PHP

1.1k176.3M97](/packages/behat-gherkin)[jakubledl/dissect

Lexing and parsing in pure PHP

2244.6M11](/packages/jakubledl-dissect)[parsica-php/parsica

The easiest way to build robust parsers in PHP.

412140.4k4](/packages/parsica-php-parsica)[jejik/mt940

An MT940 bank statement parser for PHP

911.2M2](/packages/jejik-mt940)[kingsquare/php-mt940

Simple MT940 parser in PHP

105806.1k2](/packages/kingsquare-php-mt940)[vstelmakh/url-highlight

Library to parse urls from string input

102849.1k9](/packages/vstelmakh-url-highlight)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
