rectorphp/rector · error · InvalidEregException
an invalid escape sequence at the end
Error message
an invalid escape sequence at the end
What it means
The ERE pattern being converted to PCRE ends with a lone backslash (EregToPcreTransformer.php:148). A trailing '\' opens an escape sequence but has nothing to escape, which is invalid in POSIX ERE, so EregToPcreTransformer throws InvalidEregException and the ereg-to-preg rewrite of that call aborts.
Source
Thrown at rules/Php70/EregToPcreTransformer.php:148
throw new InvalidEregException('unescaped metacharacter "' . $char . '"');
}
} elseif ($char === '.') {
$r[$rr] .= $char;
} elseif ($char === '^' || $char === '$') {
$r[$rr] .= $char;
++$i;
continue;
} elseif ($char === '|') {
if ($r[$rr] === '') {
$normalizeUnprintableChar = \true;
}
$r[] = '';
++$rr;
++$i;
continue;
} elseif ($char === '\\') {
if (++$i >= $l) {
throw new InvalidEregException('an invalid escape sequence at the end');
}
$r[$rr] .= $this->_ere2pcre_escape($content[$i]);
} else {
// including ] and } which are allowed as a literal character
$r[$rr] .= $this->_ere2pcre_escape($char);
}
++$i;
if ($i >= $l) {
break;
}
// piece after the atom (only ONE of them is possible)
$char = $content[$i];
if (in_array($char, ['*', '+', '?'], \true)) {
$r[$rr] .= $char;
++$i;
} elseif ($char === '{') {
$i = (int) $i;
$i = $this->processCurlyBracket($content, $i, $r, $rr);View on GitHub (pinned to 408fcb0ff1)
Solutions
- Fix the literal in the file Rector reported: double the trailing backslash so it becomes an escaped literal '\\\\' (ERE for one literal backslash), or drop it if it was accidental.
- Re-run rector to confirm the ereg call now converts to preg_match cleanly.
- In bulk migrations, grep ereg/split string literals for patterns ending with an odd number of backslashes first.
Example fix
// before - pattern ends with lone backslash (PHP string 'C:\\path\\' => C:\path\)
ereg('C:\\path\\', $subject);
// after - trailing backslash escaped
ereg('C:\\path\\\\\\\\', $subject); Defensive patterns
Strategy: try-catch
Validate before calling
// quick lint: pattern ends with an odd run of backslashes
function endsInLoneBackslash(string $p): bool {
$n = 0; $i = strlen($p) - 1;
while ($i >= 0 && $p[$i] === '\\') { $n++; $i--; }
return $n % 2 === 1;
} Try / catch
try {
$pcre = $eregToPcreTransformer->transform($pattern, $ignoreCase);
} catch (InvalidEregException $e) {
// trailing escape with nothing to escape — double or drop the final backslash
continue;
} Prevention
- In single-quoted PHP strings a trailing '\\' is a real backslash; double it when it must be a literal in ERE ('\\\\').
- Be extra careful with Windows-path patterns; verify the literal ends with an even number of backslashes.
- Run the transformer over collected literals once before the real rector pass.
When it happens
Trigger: Rector (Php70 set / EregToPregMatchRector, target PHP >= 7.0) visits an ereg-family call whose first argument is a string literal ending in a backslash. Note PHP string semantics: "abc\\" in source is the 4-char pattern abc\ and triggers it; 'C:\path\' with a real trailing backslash also does. After the '\' branch does ++$i >= $l, the exception 'an invalid escape sequence at the end' is thrown.
Common situations: Windows path or DOS-prefix patterns ('C:\\') where the final backslash was meant literally but never doubled; patterns chopped by an edit so the escaped character after '\' was lost; PHP single-quoted strings where the author did not realize a trailing '\' is a literal backslash that ERE cannot carry at the end.
Related errors
- unescaped metacharacter ")"
- "[" does not have a matching "]"
- unescaped metacharacter "%s"
- empty regular expression or branch
- "(" does not have a matching ")"
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/1749886957573857.
Report an issue: GitHub.