Before this lesson
Understand character classes, quantifiers and greedy matching. Be able to inspect exec results.
What you will be able to do
Extract fields and distinguish captures from grouping-only constructs.
Understand the mechanism
(a|b) scopes alternatives inside a group. ^cat|dog$ means starts with cat or ends with dog, unlike ^(?:cat|dog)$. Check the alternative scope before the anchors.
Ordinary parentheses create numbered captures, (?:...) groups without capturing, and (?<name>...) creates a named capture. Named fields reduce maintenance errors when group numbering changes.
A match does not finish semantic validation. This version pattern accepts unsigned integers without multi-digit leading zeros. Parsed numbers still need project-specific limits to stay within safe-integer range.
Runnable example
const version = /^v(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)$/;
const match = version.exec("v12.3");
console.log(JSON.stringify(match ? [match.groups.major, match.groups.minor] : null));
console.log(version.test("v01.3"));
console.log(/^(?:cat|dog)$/.test("catfish"));
console.log(/^(?<word>[a-z]+)-\k<word>$/.test("go-go"));
Trace and verify
Named captures return the strings 12 and 3. v01.3 and catfish are rejected. The named backreference requires the second word to repeat the first, accepting go-go.
Common mistakes and boundaries
Guard against null before accessing groups. A backreference repeats captured text, not the subpattern with arbitrary new text.
Practice challenge
Add a patch field so v12.3.0 passes and v12.3 fails.
Reference solution and reasoning
Add \.(?<patch>0|[1-9]\d*) before the end anchor. All three captures remain strings; validate ranges before numerical conversion.