← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Named Capture Groups

regex PHP 5.3+ Intermediate

Also Known As

named capture (?P<n>) PCRE named group

TL;DR

(?P<n>pattern) in PHP/PCRE for self-documenting regex — accessing matches by name instead of positional index.

Explanation

Named capture groups in PHP/PCRE: (?P<n>pattern) or (?<n>pattern). Access via $matches['name'] instead of $matches[1]. Benefits: self-documenting patterns, index-independent (reordering groups does not break code), easier to maintain. Backreferences: (?P=name) in pattern, ${name} in preg_replace replacement strings.

Common Misconception

Numbered groups are just as readable as named groups — $matches[3] is opaque; $matches['year'] is self-documenting. With more than 2-3 groups, names are essential for maintainability.

Why It Matters

A date regex with numeric groups breaks silently if group order changes — named groups ensure $matches['year'] always refers to the year regardless of pattern changes.

Common Mistakes

  • Numbered groups when there are more than 3
  • Not using ${name} in preg_replace replacement strings
  • Naming groups in alternations where only one branch matches — others return empty string
  • Group names with invalid characters — must match [A-Za-z_][A-Za-z0-9_]*

Code Examples

✗ Vulnerable
// Numbered groups — fragile:
preg_match('/(\d{4})-(\d{2})-(\d{2})/', '2026-03-16', $m);
$year  = $m[1]; // Breaks if pattern is reordered
$month = $m[2];
$day   = $m[3];
✓ Fixed
// Named groups — readable and stable:
preg_match('/(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})/', '2026-03-16', $m);
$year  = $m['year'];  // Self-documenting
$month = $m['month'];
$day   = $m['day'];

// Named backreference:
preg_match('/<(?P<tag>\w+)>[^<]*<\/(?P=tag)>/', '<b>bold</b>', $m);
// (?P=tag) ensures opening and closing tag are the same

Tags


Added 16 Mar 2026
Edited 5 Apr 2026
Views 27
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 1 ping S
Amazonbot 1 Perplexity 1
Amazonbot 7 Perplexity 5 Unknown AI 2 Ahrefs 2 Google 1 Bing 1
crawler 18
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use named captures (?P<year>\d{4}) instead of numbered ones — $matches['year'] is self-documenting and doesn't break when you add new groups before it
📦 Applies To
PHP 5.3+ any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
$matches[1] $matches[2] accessing captures by index; adding new group before existing group breaking all downstream index references
Auto-detectable: ✗ No phpstan phpcs
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✓ Auto-fixable Fix: Low Context: Line

✓ schema.org compliant