Regex Possessive Quantifier Conflict

ID

java.regex_possessive_quantifier_conflict

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

code-style

Description

Reports a possessive repetition (X*+, X++, X{n,}+) over a single character or simple class X, immediately followed by a mandatory character or class whose set is already fully covered by X.

Rationale

A possessive quantifier consumes every character it can and never gives any back — unlike a greedy quantifier, it does not backtrack to free one up for what follows. If what follows can only be a character X already claimed, that sub-pattern can never get one:

Pattern.compile("a++a");
// the possessive '+' eats every 'a' in the run; the trailing 'a' never gets one
Pattern.compile("\\d*+[02468]");
// '\d*+' eats every digit, so an even digit right after it never gets one either

Remediation

Give the following sub-pattern back a character to work with — split off one repetition, or use a greedy quantifier where backtracking is actually wanted:

Pattern.compile("aa++bc");        // the possessive body no longer overlaps what follows
Pattern.compile("\\d*+(?<=[02468])"); // a lookbehind consumes nothing, so there is no conflict

What is not reported

Only the atom immediately touching the quantifier on each side is examined. aa++bc is compliant: the possessive quantifier’s own body is just the second a, and b was never something it could have consumed — the first a, one position further back, does not enter into this rule’s local check. A lookbehind right after the quantifier consumes nothing and is compliant for the same reason. Greedy and reluctant quantifiers are out of scope; only possessive ones are checked.

© 2026 Xygeni. All rights reserved