{"record":{"id":"eba0d9d2177c5103","repo":"rectorphp/rector","slug":"does-not-have-a-matching","errorCode":null,"errorMessage":"\"[\" does not have a matching \"]\"","messagePattern":"\"\\[\" does not have a matching \"\\]\"","errorType":"validation","errorClass":"InvalidEregException","httpStatus":null,"severity":"error","filePath":"rules/Php70/EregToPcreTransformer.php","lineNumber":113,"sourceCode":"        $r = [''];\n        $rr = 0;\n        $l = strlen($content);\n        $normalizeUnprintableChar = \\false;\n        while ($i < $l) {\n            // atom\n            $char = $content[$i];\n            if ($char === '(') {\n                $i = (int) $i;\n                $i = $this->processBracket($content, $i, $l, $r, $rr);\n            } elseif ($char === '[') {\n                ++$i;\n                $cls = '';\n                if ($i < $l && $content[$i] === '^') {\n                    $cls .= '^';\n                    ++$i;\n                }\n                if ($i >= $l) {\n                    throw new InvalidEregException('\"[\" does not have a matching \"]\"');\n                }\n                $start = \\true;\n                $i = (int) $i;\n                [$cls, $i] = $this->processSquareBracket($content, $i, $l, $cls, $start);\n                if ($i >= $l) {\n                    throw new InvalidEregException('\"[\" does not have a matching \"]\"');\n                }\n                $r[$rr] .= '[' . $cls . ']';\n            } elseif ($char === ')') {\n                break;\n            } elseif (in_array($char, ['*', '+', '?'], \\true)) {\n                throw new InvalidEregException('unescaped metacharacter \"' . $char . '\"');\n            } elseif ($char === '{') {\n                if ($i + 1 < $l && strpos('0123456789', $content[$i + 1]) !== \\false) {\n                    $r[$rr] .= '\\{';\n                } else {\n                    throw new InvalidEregException('unescaped metacharacter \"' . $char . '\"');\n                }","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/rules/Php70/EregToPcreTransformer.php#L95-L131","documentation":"While converting an ERE pattern to PCRE, EregToPcreTransformer encountered a '[' (optionally followed by '^') at the very end of the pattern, so the character class has no chance of being closed. POSIX ERE requires every '[' to be matched by ']', so the pattern is invalid and InvalidEregException is thrown, aborting the EregToPregMatchRector conversion.","triggerScenarios":"Rector (Php70 set / EregToPregMatchRector, target PHP >= 7.0) visits an ereg-family call whose first argument is a string literal ending in '[' or '[^', e.g. `ereg('abc[', $s)` or `split('[^', $s)`. The check at EregToPcreTransformer.php:113 fires because the index after consuming '[' (and optional '^') already reached the end of the string.","commonSituations":"Legacy PHP 5 era code with typo'd character classes; a pattern truncated by a bad edit or a mis-quoted heredoc; concatenated pattern fragments where the closing ']' lived in a variable that is now a literal.","solutions":["Open the file Rector reported and complete the character class: turn 'abc[' into 'abc[x]' for the intended character set, or escape it as 'abc\\[' if '[' is meant literally.","Re-run rector on the file to verify the ereg-to-preg conversion completes.","Preflight large migrations by scanning for string-literal ereg patterns that end in '[' or '[^' and fixing them first."],"exampleFix":"// before - unterminated character class\nereg('abc[', $subject);\n\n// after - closed class (or escape the bracket if literal)\nereg('abc[a-z]', $subject); // rector: preg_match('#abc[a-z]#m', $subject)","handlingStrategy":"try-catch","validationCode":"$ok = true;\nforeach (['abc[', 'x[^'] as $candidate) {\n    try { (new EregToPcreTransformer())->transform($candidate, false); }\n    catch (InvalidEregException $e) { $ok = false; echo \"Unterminated class: {$candidate}\\n\"; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    $pcre = $eregToPcreTransformer->transform($pattern, $ignoreCase);\n} catch (InvalidEregException $e) {\n    // pattern ends right after '[' or '[^' — close the class in the source and re-run\n    continue;\n}","preventionTips":["Treat '[' without a following ']' in any literal regex as a build-breaking typo; fix before the migration run.","When truncating or concatenating patterns, assert the result still ends outside a character class.","Pre-check literal patterns with the transformer in a scratch script before running rector over the whole repo."],"tags":["rector","php","regex","posix-ere","character-class","migration"],"backgroundTag":"invalid-regex-syntax","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}