Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Regex Laravel Package

hoa/regex

Hoa\Regex is a PHP library for working with regular expressions at the grammar level. It parses patterns into an AST, offers visitors and generators, and supports analyzing, manipulating, and compiling regexes for advanced tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

hoa/regex is not a regex engine — it is a parser and AST toolkit for PCRE. That distinction matters: you do not swap preg_match() for it. You use it when you need to look inside a pattern (enumerate matching strings, generate fixtures, inspect structure, rewrite a pattern) rather than just execute it.

Before you install anything, check the environment. The package is archived, last released 2017-01-13, and pulls in a chain of hoa/* libraries (compiler, file, math, stream, ustring, iterator, protocol, consistency, zformat). On modern PHP (8.x) you will typically need composer require hoa/regex --ignore-platform-reqs, or a community fork, and even then hoa/protocol's hoa:// stream wrapper can trip over opcache preloading. Verify with a throwaway script before committing a codebase to it.

Where to look first, in order:

  1. The grammar file the whole thing revolves around: vendor/hoa/regex/Grammar/Pcre.pp (reachable at hoa://Library/Regex/Grammar/Pcre.pp once the wrapper is registered).
  2. vendor/hoa/regex/Visitor/ — especially Isotropic.php and Uniform.php (string sampling) and ToPcre.php (AST back to a pattern).
  3. vendor/hoa/regex/Ast/Node/ — the node types you will walk if you write a visitor.
  4. The GitHub README, which is short and mostly example code.

First use case — generate a string that matches a validation rule. This is the single most useful thing a Laravel developer gets out of the library: producing realistic data that satisfies a FormRequest rule or a JS-side pattern, without hand-writing fixtures.

use Hoa\Compiler\Llk\Llk;
use Hoa\File\Read;
use Hoa\Math\Sampler\Random;
use Hoa\Regex\Visitor\Isotropic;

$compiler = Llk::load(new Read('hoa://Library/Regex/Grammar/Pcre.pp'));
$ast      = $compiler->parse('/^[A-Z]{2}[0-9]{6}$/');

$sampler = new Isotropic(new Random());

for ($i = 0; $i < 5; $i++) {
    dump($sampler->visit($ast)); // "QD482913", "MK004411", ...
}

Note that the input is the full delimited pattern, not a bare regex body — that is the first thing that will bite you (see below).

Implementation Patterns

1. Wrap it in a singleton service, never instantiate per call. Loading the LL(k) grammar is the expensive part (milliseconds, sometimes tens of milliseconds), and the parsed AST is immutable and reusable. Register once:

// app/Providers/AppServiceProvider.php
$this->app->singleton(RegexFaker::class);

// app/Support/RegexFaker.php
final class RegexFaker
{
    private Llk $compiler;
    private array $cache = [];

    public function __construct()
    {
        $this->compiler = Llk::load(new Read('hoa://Library/Regex/Grammar/Pcre.pp'));
    }

    public function sample(string $pcre, int $count = 1): array
    {
        $ast = $this->cache[$pcre] ??= $this->compiler->parse($pcre);
        $gen = new Isotropic(new Random());

        return array_map(fn () => $gen->visit($ast), range(1, $count));
    }
}

2. Model factories. A custom Faker provider keeps call sites idiomatic:

$factory->define(Ticket::class, fn () => [
    'code' => app(RegexFaker::class)->sample('/^[A-Z]{2}[0-9]{6}$/')[0],
]);

3. Property-based tests for validation rules. Generate N matching strings and N near-misses (flip a character of a generated string) and assert your FormRequest accepts/rejects them. This catches rules that are accidentally too loose or too strict far better than three hand-picked examples.

4. AST walking for "is this pattern safe?" checks. Implement Hoa\Visitor\Visit (or extend Hoa\Visitor\Element) and traverse the AST counting nested quantifiers over character classes — a cheap ReDoS heuristic you can run as a CI gate over patterns users submit (e.g. saved search filters, custom validation rules in an admin panel). The library gives you structure that preg_match obviously cannot.

5. Pattern normalization / round-trip. Parse → mutate the AST (strip anchors, force the u flag, rename groups, bound + to {1,10}) → render with Hoa\Regex\Visitor\ToPcre. Useful when you let users author a pattern and need to sanitize or bound it before storing.

6. Artisan command for CI. php artisan regex:lint that greps preg_* calls and Rule:: patterns from your registry and reports anything the grammar cannot parse. Treat failures as warnings, since the PCRE grammar doesn't cover every PHP feature. Keep this in console/tests only — never in the HTTP hot path.

7. Bound unbounded quantifiers before sampling. .*, \w+, [a-z]+ can yield absurdly long or empty strings depending on the sampler's weighting. Pre-process patterns (or the AST) to cap */+ at something like {1,12} when generating fixtures.

Gotchas and Tips

  • Archived and unmaintained. Zero dependents on record, no release since 2017. Assume no PHP 8/9 fixes are coming. Pin the version, and seriously consider fake()->regexify($pattern) from fakerphp/faker if all you need is fixture generation — it's already in every Laravel app and has no AST baggage. Reach for hoa/regex only when you need the AST.
  • Delimiters are mandatory. parse('/foo/i') works; parse('foo') fails with a confusing lexer error. Strip nothing, add nothing — pass the exact string you'd give preg_match.
  • Anchors and lookarounds poison sampling. ^, $, \b, (?=...), (?<=...) are structural, not characters. Sampling a pattern that contains them either produces nothing sensible or throws. Strip anchors/boundaries before generating; keep them for analysis.
  • \p{...}, \K, (?R), possessive quantifiers, conditional groups may not exist in the 2017-era grammar. If parse() throws on a real-world pattern, that is a parser limitation, not an invalid regex — don't surface it to users as "invalid pattern".
  • Register the hoa:// protocol explicitly if you get "stream not found" errors: Hoa\Protocol\Wrapper::register(); (or Hoa\Protocol\Protocol::getInstance() bootstrapping). This is the #1 install-time failure under Laravel, and it interacts badly with opcache preloading and some FPM setups.
  • Errors are Hoa\Compiler\Exception with hoa:// paths in the message. Catch and remap them to something human-readable before they hit a log or a user.
  • Unicode surprises. The package depends on hoa/ustring; invalid UTF-8 input and \u{...} escapes are a common source of throws on the sampling path. Sanitize input patterns with mb_check_encoding($p, 'UTF-8').
  • Isotropic vs Uniform. Isotropic weights by the cardinality of the language, so it mirrors the distribution of what the pattern accepts. Uniform samples more evenly. For fake data you usually want uniform-looking output, so try both before assuming one is "correct".
  • Extension point. Custom visitors against Hoa\Regex\Ast\Node\* are clean and the intended way to add analysis; keep them outside app/Http so the dependency doesn't leak into controllers.
  • Budget for removal. If you adopt this, isolate it behind one interface (RegexAnalyzer, RegexFaker) with a faker-based fallback implementation. Given the package's status, that seam is what makes the eventual swap a one-file change instead of a refactor.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package