php-regex / regex-cli
The regex console: sixteen subcommands to parse, explain, validate, lint, hunt ReDoS, transpile, diagram and debug patterns — also shipped as a self-updating regex.phar.
Fund package maintenance!
Requires
- php: >=8.1
- ext-mbstring: *
- php-regex/regex-automata: 2.x-dev
- php-regex/regex-explain: 2.x-dev
- php-regex/regex-linter: 2.x-dev
- php-regex/regex-optimizer: 2.x-dev
- php-regex/regex-parser: 2.x-dev
- php-regex/regex-redos: 2.x-dev
- php-regex/regex-toolkit: 2.x-dev
- php-regex/regex-transpiler: 2.x-dev
Requires (Dev)
None
Suggests
- php-regex/regex-language-server: To run the language server with regex lsp.
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-27 10:05:53 UTC
README
PHPRegex CLI
The regex console: sixteen subcommands to parse, explain, validate, lint, hunt ReDoS, transpile, diagram and debug patterns — also shipped as a self-updating regex.phar.
Documentation: php-regex.com — the CLI guide takes the sixteen subcommands one by one.
Features
- Lints a whole codebase: patterns extracted from
preg_*calls,RegexIteratorandfilter_var(), eight library presets and your own helpers, followed through the variables, constants and properties of the same file, then judged by 53 lint rules. - ReDoS verdicts proven on a model of PCRE's backtracking, with the input that triggers a vulnerable pattern; confirmed mode replays it on the running PCRE — plus a benchmark command.
- Automata comparison of two patterns: intersection, subset, equivalence, with counter-examples.
- Transpiles PCRE patterns to JavaScript, HTML
patternattributes and Python; renders the AST as text or SVG and the NFA as DOT or Mermaid. - CI-ready reports in five formats with three stable exit codes, and a self-updating
regex.phar.
Installation
composer require --dev php-regex/regex-cli
The binary is vendor/bin/regex and requires PHP 8.1+.
Standalone phar
curl -Ls https://github.com/php-regex/php-regex/releases/latest/download/regex.phar -o ~/.local/bin/regex && chmod +x ~/.local/bin/regex regex self-update
The phar is built from the release tag by a GitHub Actions workflow and
attested: gh attestation verify ~/.local/bin/regex --repo php-regex/php-regex
checks that yours is that build.
Commands
| Command | Description | Command | Description |
|---|---|---|---|
parse |
Parse and recompile a pattern | highlight |
Highlight a regex for display |
analyze |
Parse, validate, analyze ReDoS risk | validate |
Validate a pattern |
compare |
Compare two patterns (automata) | transpile |
Transpile to js, html or python |
explain |
Explain a pattern in plain language | lint |
Lint patterns in PHP sources |
debug |
Deep ReDoS analysis, heatmap | version |
Display version information |
redos |
Benchmark patterns for ReDoS | self-update |
Update the phar in place |
diagram |
AST diagram, text or SVG | help |
Display the help message |
graph |
NFA graph, DOT or Mermaid | format |
Lay a pattern out over lines, or compact it |
lsp |
Run the language server (the phar carries it) |
Configuration
Global options:
| Option | Effect |
|---|---|
--ansi / --no-ansi |
Force or disable ANSI output |
-q, --quiet, --silent |
Suppress output |
--no-visuals |
Disable banner and section visuals |
--php-version <ver> |
Target PHP version for validation |
--pcre-version <ver> |
Target PCRE2 release for validation |
--locale <name> |
Target LC_CTYPE locale for validation |
--cache-dir <dir> |
Keep the Unicode class scans in <dir> for the next run |
lint reads defaults from regex.json or regex.dist.json in the working directory — paths, excludes, extraction interop, which checks run. Command-line options win; --output <file> writes the report to a file.
Every command exits 0 when it found nothing wrong, 1 when the patterns or files it judged have a problem, 2 when the command line or configuration cannot be used.
Usage
Validate a pattern — the hello world of the console (outputs below come from --no-visuals runs):
vendor/bin/regex validate '/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i' --no-visuals # Pattern: /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i # Status: OK vendor/bin/regex validate '/(?<=a+)b/' --no-visuals # exits 1 # Pattern: /(?<=a+)b/ # Status: INVALID # Lookbehind is unbounded. PCRE requires a bounded maximum length. # Line 1: (?<=a+)b # ^
analyze adds a ReDoS report before explaining the pattern:
vendor/bin/regex analyze '/(a+)+$/' --no-visuals # Pattern: /(a+)+$/ # Parse: OK # Status: OK # Status: Exponential backtracking (proven) # Severity: CRITICAL (score 10) # Mode: THEORETICAL # Confidence: MEDIUM # Attack: "a" x n . "!" # Hotspot: 1-3
lint walks PHP sources and reports in five formats; with --format=github each finding becomes an annotation GitHub renders natively:
vendor/bin/regex lint src/ --format=github --no-visuals # Target: PHP 8.2, PCRE2 10.40 (composer.json require.php) # ::notice file=src/demo.php,line=3,col=12,title=Lint (regex.lint.group.quantifiedCapture)::Quantified capturing group "(...)" with "+": only the last iteration's capture is retained.%0ASuggestion: Use a non-capturing group (?:...) for the repetition and capture the whole match, or restructure the pattern.%0ARead more: https://php-regex.com/reference/rules/#quantified-capturing-group # ::warning file=src/demo.php,line=3,col=12,title=Lint (regex.lint.quantifier.nested)::Nested quantifiers can cause catastrophic backtracking.%0ASuggestion: Consider atomic groups (?>...) or possessive quantifiers — verify the rewrite still matches everything you need.%0ARead more: https://php-regex.com/reference/rules/#nested-quantifiers-redos-risk
transpile writes the pattern for another engine:
vendor/bin/regex transpile '/[a-z]+\d/' --target=js --no-visuals # Target: JAVASCRIPT # Source: /[a-z]+\d/ # ... # Constructor: # new RegExp("[a-z]+\\d", "")
Documentation
- Quick start — from installation to a first analysis.
- CLI guide — every subcommand in depth, the lint configuration file, CI recipes.
- ReDoS guide — the risky shapes, the two analysis modes, mitigation.
- Backward compatibility — the promise that holds across 2.x.
Resources
- Upgrading from 1.x — moving from
yoeunes/regex-parser1.3 to 2.0, every change that needs one on your side - Changelog
- All PHPRegex packages, released with their siblings under one version number
- Report issues and send pull requests in the main PHPRegex repository
Sponsors
If PHPRegex saves you time, consider sponsoring its maintenance.
License
MIT. See LICENSE.