rectorphp/rector · error · InvalidEregException

empty regular expression or branch

Error message

empty regular expression or branch

What it means

After parsing the whole ERE pattern (or a branch), EregToPcreTransformer found the last branch empty — the pattern itself is '' or it ends with '|' leaving nothing after it (EregToPcreTransformer.php:170). POSIX ERE forbids empty patterns and empty alternation branches, so the conversion to PCRE is refused with InvalidEregException('empty regular expression or branch').

Source

Thrown at rules/Php70/EregToPcreTransformer.php:170

                // 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);
            }
        }
        if ($r[$rr] === '') {
            throw new InvalidEregException('empty regular expression or branch');
        }
        return [$this->normalize(implode('|', $r), $normalizeUnprintableChar), $i];
    }
    private function normalize(string $content, bool $normalizeUnprintableChar): string
    {
        if ($normalizeUnprintableChar) {
            $content = str_replace("\f", '\\\\f', $content);
        }
        return str_replace($this->pcreDelimiter, '\\' . $this->pcreDelimiter, $content);
    }
    /**
     * @param array<int, mixed> $r
     */
    private function processBracket(string $content, int $i, int $l, array &$r, int $rr): int
    {
        // special case
        if ($i + 1 < $l && $content[$i + 1] === ')') {
            $r[$rr] .= '()';

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Give the pattern real content: replace '' with the intended expression, and remove the trailing '|' ('a|' -> 'a').
  2. If the pattern is built dynamically, guard it so it cannot become empty before the ereg call.
  3. Re-run rector; preflight-scan literal ereg/split patterns for '' and trailing '|'.

Example fix

// before - trailing alternation with empty branch
split('a|', $subject);

// after - complete alternation
split('a|b', $subject); // rector: preg_split('#a|b#m', $subject)
Defensive patterns

Strategy: validation

Validate before calling

// guard dynamically built patterns before the legacy call
if ($pattern === '' || substr($pattern, -1) === '|') {
    throw new InvalidArgumentException('ereg pattern must be non-empty and must not end with |');
}

Try / catch

try {
    $pcre = $eregToPcreTransformer->transform($pattern, $ignoreCase);
} catch (InvalidEregException $e) {
    // pattern or final alternation branch is empty — give it content
    continue;
}

Prevention

When it happens

Trigger: Rector with the Php70 set / EregToPregMatchRector (target PHP >= 7.0) encounters an ereg-family call whose literal first argument is '' or ends with '|', e.g. `ereg('', $s)`, `split('a|', $s)`, or `ereg('|a', $s)` (the leading-empty branch only throws if the final branch is also empty, but trailing '|' always does). The final check `if ($r[$rr] === '')` fires before normalize() runs.

Common situations: Placeholder/empty-string patterns passed to split() to split on 'nothing'; dynamically built patterns whose optional chunk was empty; refactors that removed the last alternative but left the '|' separator.

Related errors


AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21). Data as JSON: /api/errors/9390fd1fc9d409bd. Report an issue: GitHub.