This guide helps you resolve common issues when using RegexParser.
Problem:
RegexParser\Exception\ResourceLimitException: Regex pattern exceeds maximum length of 100000 characters.
Causes:
- You're parsing a generated pattern or loading patterns from database
- Pattern is too large for your application's needs
Solutions:
- Increase limit:
$regex = Regex::create([
'max_pattern_length' => 1_000_000, // 1 million characters
]);- Validate pattern before storing:
$regex = Regex::create();
$validation = $regex->validate($pattern);
if (!$validation->isValid) {
throw new \InvalidArgumentException("Invalid pattern: {$validation->error}");
}- Use cache to skip parsing:
$regex = Regex::create([
'cache' => new \FileCache('/tmp/regex_cache'),
// Pattern parsed once, cached for all workers
]);- Check pattern length before parsing:
if (strlen($pattern) > 100_000) {
throw new \RuntimeException("Pattern too long: " . strlen($pattern) . " characters");
}Problem: Your ReDoS analyzer reports HIGH but pattern works fine.
Cause: ReDoS analysis is structural and conservative by design.
Solutions:
- Run confirmed mode:
$regex = Regex::create();
$result = $regex->redos(
$pattern,
ReDoSSeverity::HIGH,
ReDoSMode::CONFIRMED, // ← Test with real inputs
new ReDoSConfirmOptions(
maxTestStrings: 1000,
maxStringLength: 1000,
)
);
echo "Confirmed: " . ($result->isConfirmed ? 'Yes' : 'No') . "\n";
echo "Confidence: {$result->confidence->value}\n";- Add to ignore list:
$regex = Regex::create([
'redos_ignored_patterns' => [
'your-safe-pattern-1',
'your-safe-pattern-2',
],
]);- Understand structural analysis:
// Theoretical mode finds POTENTIAL risks
// It's designed to be conservative and catch more
// These patterns are flagged because they COULD be dangerous
$riskyPatterns = [
'/(a+)+$/', // Classic ReDoS example
'/^(\d+)+$/', // Nested quantifiers
'/(a+)+b+/', // Alternation in quantifiers
];
// In practice, with realistic input, these might be safe
$realisticInputs = [
'hello', // No backtracking
'test123', // No backtracking
];Problem:
RegexParser\Exception\LexerException: Invalid escape sequence '\c' at position 5
Causes:
- Using PCRE escape syntax not supported by your PHP version
- Typo in escape sequence
- Confusing escape with literal character
Solutions:
- Check PHP version:
php -v
php --re
# Output PCRE library version
# PHP 8.2 uses PCRE2 10.30+
# Newer versions support more escape sequences- Use correct escape syntax:
// Wrong
$pattern = '\cA'; // Control character A
// Correct
$pattern = '\x01'; // Hexadecimal (recommended)
$pattern = '\x{41}'; // Hexadecimal with braces- Fix common typos:
// Wrong Correct
'\d' → '\\d' // Double backslash
'\N{' → '\N{U+XXXX}' // Full Unicode name
'\p{' → '\p{...}' // Property needs braces
'\u{' → '\u{...}' // Hex needs braces for > 2 digitsProblem:
RegexParser\Exception\LexerException: Unable to tokenize pattern at position 15. Context: "abc..."
Causes:
- Malformed UTF-8 input
- Unsupported PCRE syntax
- Invalid character class nesting
Solutions:
- Validate UTF-8 encoding:
if (!preg_match('//u', $pattern)) {
throw new \RuntimeException('Pattern must be valid UTF-8');
}- Check for obvious syntax errors:
// Check for unmatched brackets
$openBrackets = substr_count($pattern, '[');
$closeBrackets = substr_count($pattern, ']');
if ($openBrackets !== $closeBrackets) {
throw new \RuntimeException('Unmatched character class brackets');
}
// Check for unmatched parentheses
$openParens = substr_count($pattern, '(');
$closeParens = substr_count($pattern, ')');
if ($openParens !== $closeParens) {
throw new \RuntimeException('Unmatched parentheses');
}Problem: Regex matching is taking too long on your input.
Diagnosis:
- Check for catastrophic backtracking:
bin/regex analyze '/(a+)+$/' --mode=confirmed
# If confirmed mode takes > 10ms per test,
# you likely have a ReDoS issue- Check for unnecessary backtracking:
bin/regex debug '/.*a.*b.*a.*/' --heatmap
# Heatmap will show where backtracking occurs- Test with realistic data:
// Test with your actual data, not edge cases
$realisticData = $yourActualProductionData();
$start = microtime(true);
preg_match($yourPattern, $realisticData);
$elapsed = microtime(true) - $start;
echo "Time: " . ($elapsed * 1000) . " ms\n";- Use caching:
$regex = Regex::create([
'cache' => new \FileCache('/tmp/regex_cache'),
]);
// Parse once, reuse across requests
$ast = $regex->parse($pattern);Problem: Cache is not being used, patterns are parsed on every request.
Solutions:
- Verify cache is configured:
$regex = Regex::create([
'cache' => new \FileCache('/tmp/regex_parser_cache'),
]);
// Test
$ast1 = $regex->parse('/\d+/');
$ast2 = $regex->parse('/\d+/'); // Should use cache
echo "Cache enabled: " . ($regex->getCacheStats()['hits']) . " hits\n";- Clear cache for long-running processes:
# CLI
bin/regex clear-cache
# Programatically
$cache = $regex->getCache();
if ($cache instanceof RemovableCacheInterface) {
$cache->clear();
}- Check cache key generation:
// Cache keys include pattern, flags, and PHP version
// Make sure these are correct for your use case
$cacheKey = $cache->generateKey('/\d+/i');
echo "Cache key: {$cacheKey}\n";Problem:
Command "regex:test" is not defined.
Solutions:
- Use
helpcommand to list available commands:
bin/regex help- Update to latest version:
composer update
# or
composer require yoeunes/regex-parser@latest- Check if command is deprecated:
bin/regex help | grep -i deprecated
# Use alternative commandProblem: Symfony bundle commands not found or not working.
Solutions:
- Verify bundle is installed:
composer show yoeunes/regex-parser
# Check if Symfony bridge is listed- Register bundle in Symfony:
# config/bundles.php
return [
RegexParser\Bridge\Symfony\RegexParserBundle::class => ['all' => true],
];- Clear Symfony cache:
php bin/console cache:clear
# Or
rm -rf var/cache/*Problem: Tests pass with one version but fail with newer version.
Solutions:
- Run tests after upgrade:
composer phpunit
# Run specific test file
composer phpunit tests/Unit/Parser/ParserTest.php- Update test expectations:
// Check if test needs updating after API changes
// Before
public function test_parse_handles_new_feature(): void
{
$result = $this->regex->parse('/new-syntax/');
$this->assertInstanceOf(NewNode::class, $result->child);
}
// After API change
public function test_parse_handles_new_feature(): void
{
$result = $this->regex->parse('/new-syntax/');
$this->assertInstanceOf(DifferentNode::class, $result->child); // Updated expectation
}- Check deprecation warnings:
# Run with error reporting
composer phpunit --display-deprecations
# Fix deprecations before running full test suiteProblem: Documentation doesn't explain what you need to do.
Solutions:
- Check Quick Start Guide:
# docs/QUICK_START.md- Check API Reference:
# docs/reference.md- Look at examples:
ls -la examples/
php examples/basic/validate.php- Search issues:
# Search GitHub issues
https://github.com/yoeunes/regex-parser/issues
# Create new issue with question- Join community:
# GitHub Discussions
https://github.com/yoeunes/regex-parser/discussions
# Stack Overflow
https://stackoverflow.com/questions/tagged/regexparser- Quick Start Guide
- API Reference
- ReDoS Guide
- Architecture Documentation
- Contributing Guide
- Upgrading Guide
- Check the GitHub Issues for similar problems
- Search for your specific error message in the codebase
- Enable verbose mode for more details:
bin/regex analyze '/pattern/' -v