Unmatchable Boundary

ID

php.regex_unmatchable_boundary

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Php

Tags

regex, reliability

Description

Reports a boundary (^, $, \A, \Z, \z) placed next to input that still has to be consumed on the wrong side of it, so the pattern can never match anything.

Rationale

^ and \A match only at the start of the subject; $, \Z and \z only at the end. Swap them, or leave one where a character still has to be matched on the far side, and the pattern becomes impossible to satisfy:

// Bad
preg_match('/$[a-z]+/', 'abc');   // 0 -- and 0 for every other subject

The end boundary is already past the input by the time the character class needs a character to consume.

  • Usually a typo — ^ and $ swapped, or a boundary left behind after editing a pattern.

  • preg_match returns 0 rather than false, so nothing distinguishes this from "no match here": the guard just never fires, for any input.

Remediation

Put the boundary on the side of what it anchors.

// Good
preg_match('/^[a-z]+$/', 'abc');   // 1

What is not reported

Under the m modifier — set on the literal as /…​/m or turned on inside the pattern with (?m) — ^ and $ legitimately match mid-pattern at a line break, so the rule stays silent for both there. \A, \Z and \z are unaffected by the modifier and are still checked.

\b and \B are word boundaries, not input boundaries, and are out of scope. Only the atom immediately adjacent to the boundary is examined: a boundary next to an atom that is itself optional (?, *, {0,n}) is a related but different unmatchable shape, accepted here as a false negative rather than guessed at.

© 2026 Xygeni. All rights reserved