Match different patterns based on whether a group captured
Conditional patterns let you say "if group N captured something, match the YES branch; otherwise match the NO branch." Syntax: (?(N)yes|no) where N is a group number, or (?(name)yes|no) for named groups.
This is a niche but powerful feature. It's how you express patterns like "if there's an opening quote, require a matching closing quote; otherwise no quote requirement."
Worked example: optional bracket pairing
Pattern: (\()?\d+(?(1)\)) — "optional opening paren, then digits, then matching closing paren ONLY if we had an opener."
- Matches
123(no parens, both fine) - Matches
(123)(open + close) - Does NOT match
(123or123)(mismatched)
Flavor support
Conditionals are a PCRE feature, supported by Python re, Perl, .NET, PHP, Ruby (via Regexp::Engine). They're NOT in JavaScript, Go, or RE2.
When to reach for them
Honestly, rarely. Most patterns that benefit from conditionals can be cleaner as alternation: (?:\(\d+\)|\d+) matches the same thing as the conditional above and works in every flavor. Reach for conditionals only when the YES branch is much more complex than the NO branch and you want to avoid duplication.