php-regex / regex-explain
Explains, highlights and draws regex ASTs: plain text and HTML explanations, console and HTML highlighting, ASCII trees, Mermaid and railroad diagrams.
Fund package maintenance!
Requires
- php: >=8.1
- ext-mbstring: *
- php-regex/regex-parser: 2.x-dev
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-09 16:43:56 UTC
README
PHPRegex Explain
Explains, highlights and draws regex ASTs: plain text and HTML explanations, console and HTML highlighting, ASCII trees, Mermaid and railroad diagrams.
Every class here is a node visitor: parse once with regex-parser, then walk the AST with accept(). There is nothing to configure.
Documentation: php-regex.com — the visitor reference is the class-by-class tour.
Features
- Plain-English explanation, one line per construct (
TextExplainer) - The same explanation as HTML, each node carrying a
titletooltip (HtmlExplainer) - Terminal syntax highlighting in 24-bit ANSI colors (
Highlighter\ConsoleHighlighter) - Web syntax highlighting as
regex-tokenspans you style yourself (Highlighter\HtmlHighlighter) - ASCII tree of the AST, for logs and code review (
AsciiTreeRenderer) - Mermaid flowchart source, for Markdown and docs sites (
MermaidRenderer) - Standalone railroad-diagram SVG with its stylesheet embedded (
RailroadSvgRenderer) - Covers the parser's whole PCRE node set: groups, quantifiers, class-set operations, conditionals, subroutines, callouts
Installation
composer require php-regex/regex-explain
Requires PHP 8.1+ and php-regex/regex-parser at the same version, pulled in
automatically.
Usage
Explain a pattern in plain English:
use PHPRegex\Explain\TextExplainer; use PHPRegex\Parser\RegexParser; $ast = RegexParser::create()->parse('/[A-Z][a-z]+\d*/'); echo $ast->accept(new TextExplainer()); // Regex matches // Character Class: any character in [ Range: from 'A' to 'Z' ] // Character Class: any character in [ Range: from 'a' to 'z' ], one or more times // Character Type: A digit [0-9], zero or more times
A few readings moved across PCRE2 releases and locales: \w under u takes non-spacing marks from PCRE2 10.43,
\w and \s without u follow the tables of the LC_CTYPE locale, and (?(VERSION>=10.5) reads its minor as
two digits up to 10.46. Give the explainer the target the pattern is judged for, and each is explained as that
engine reads it; without one, the explanation names the release or the locale the reading depends on.
Regex::explain() passes the target of its instance.
use PHPRegex\Parser\PcreTarget; $ast = RegexParser::create()->parse('/\w+/u'); echo $ast->accept(new TextExplainer(new PcreTarget(80300, '10.42'))); // Regex matches (with flags: u) // Character Type: A word character: a Unicode letter (\p{L}) or number (\p{N}), or an underscore, one or more times
Print the AST itself as a tree:
use PHPRegex\Explain\AsciiTreeRenderer; $ast = RegexParser::create()->parse('/(?<year>\d{4})-\d{2}/'); echo $ast->accept(new AsciiTreeRenderer()); // Regex // \-- Sequence // |-- Group (named) name="year" // | \-- Quantifier ({4}, greedy) // | \-- CharType (\d) // |-- Literal ('-') // \-- Quantifier ({2}, greedy) // \-- CharType (\d)
Both write the text a pattern carries, a comment, a callout string or the
name of a verb such as (*MARK:…), in
display form: a control character is written \xHH (\x1B), a line break,
a tab or a carriage return \n, \t or \r, and a character that moves or
hides text such as U+202E \x{202E}. An explanation keeps one line per
construct, and the escape sequences of a pattern never reach the terminal.
Both stop at 8 MiB of output, indentation and line breaks counted: a pattern of
a few dozen kilobytes can nest a long run deep enough to need far more, and
rendering it throws a ResourceLimitException whose errorCode is
ErrorCode::RenderingOutputTooLarge (regex.rendering.output_too_large)
instead of exhausting memory. The visitor can be reused after it threw.
Highlight the pattern instead of explaining it — ANSI for a terminal, span classes for a web page:
use PHPRegex\Explain\Highlighter\ConsoleHighlighter; use PHPRegex\Explain\Highlighter\HtmlHighlighter; $ast = RegexParser::create()->parse('/\d{2,}/'); // wraps each token as \e[38;2;R;G;Bm...\e[0m (true color) echo $ast->accept(new ConsoleHighlighter()); echo $ast->accept(new HtmlHighlighter()); // <span class="regex-token regex-type regex-escape">\d</span><span class="regex-token regex-quantifier">{2,}</span>
Render an explanation ready for a web page — the title attribute holds the detail:
use PHPRegex\Explain\HtmlExplainer; echo RegexParser::create()->parse('/\d{3}-\d{4}/')->accept(new HtmlExplainer()); // <div class="regex-explain"> // <strong>Regex matches:</strong> // <ul><li><span title="Character Type: A digit [0-9], exactly 3 times">Character Type: <strong>\d</strong> (A digit [0-9])</span>, exactly 3 times</li>… // </ul> // </div>
Draw the pattern — Mermaid source for a docs page, a complete SVG for anywhere else:
use PHPRegex\Explain\MermaidRenderer; use PHPRegex\Explain\RailroadSvgRenderer; $ast = RegexParser::create()->parse('/a(b|c)*/'); echo $ast->accept(new MermaidRenderer()); // graph TD; // node0["Regex: none"] // node1["Sequence"] // node2["Literal: a"] // node1 --> node2 // node3["Quantifier: *"] // … remaining nodes and edges … file_put_contents('railroad.svg', $ast->accept(new RailroadSvgRenderer())); // a complete XML document: an <svg> root with its stylesheet embedded
Documentation
- Quick start — explain and highlight in the opening tour
- Visitor reference — every Explain class, with examples
- CLI guide — the
regex explain,highlightanddiagramcommands - Backward compatibility — what stays stable across releases
Resources
- Upgrading from 1.x — moving from
yoeunes/regex-parser1.3 to 2.0, every change that needs one on your side - All PHPRegex packages — one repo, one version number
- Changelog
- Report issues and send pull requests in the main repository
Sponsors
If PHPRegex saves you time, consider sponsoring its maintenance.
License
MIT. See LICENSE.