Note Each pair of parentheses creates a numbered capture group starting at 1. In JS, the full match is at index 0. Groups are essential for extracting parts of a match for later use.
capture groupextract partsparentheses groupsub-matchparse date
Non-Capturing Group (?:)
syntax
(?:pattern) groups without capturing
example
JS: 'http://a.com https://b.com'.match(/(?:https?):\/\/\S+/g)
Py: re.findall(r'(?:Mr|Mrs|Ms)\.\s(\w+)', 'Mr. Smith and Ms. Lee')
output
JS: ["http://a.com", "https://b.com"]
Py: ["Smith", "Lee"] (only the name is captured)
Note Use (?:) when you need grouping for alternation or quantifiers but do not need to capture the result. Reduces memory usage and keeps group numbering clean.
non-capturing groupgroup without captureefficient groupingalternation group
Named Capturing Groups
syntax
JS: (?<name>pattern) Python: (?P<name>pattern)
example
JS: const m = '2026-04-04'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
m.groups.year // "2026"
Py: m = re.search(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', '2026-04-04')
m.group('year') # '2026'
Note Syntax differs between JS and Python. JS uses (?<name>...) while Python uses (?P<name>...). Named groups dramatically improve readability of complex patterns. Both approaches also assign a numeric index.
named groupnamed capturegroup namereadable regexlabeled group
Backreferences \1
syntax
\1 \2 etc. refer to previously captured groups
example
JS: 'abcabc'.match(/(abc)\1/)
Py: re.search(r'(\w+)\s+\1', 'the the quick brown fox')
output
JS: ["abcabc", "abc"]
Py: matches "the the" (detects duplicate word)
Note The backreference matches the exact same text captured by group N, not the same pattern. Useful for detecting repeated words or matched delimiters (like matching opening and closing quotes of the same type).
backreferencerepeated groupduplicate wordsame text again\1 reference
Named Backreferences
syntax
JS: \k<name> Python: (?P=name)
example
JS: /(?<quote>['"]).*?\k<quote>/.exec(`She said "hello" and 'bye'`)
Py: re.search(r"(?P<quote>['\"]).*?(?P=quote)", 'He said "ok"')
output
JS: ['"hello"', '"']
Py: '"ok"'
Note Named backreferences are more readable than \1 in complex patterns. Syntax differs: JS uses \k<name>, Python uses (?P=name).
named backreferencenamed back referencematch same quote\k reference
Alternation |
syntax
pattern1|pattern2
example
JS: 'My cat and your dog'.match(/cat|dog/g)
Py: re.findall(r'\b(?:jpg|png|gif)\b', 'files: logo.png and bg.jpg')
output
JS: ["cat", "dog"]
Py: ["png", "jpg"]
Note The | operator has very low precedence -- /ab|cd/ matches 'ab' or 'cd', NOT 'a(b|c)d'. Always wrap alternations in a group when they are part of a larger pattern to avoid surprises.
JS: '192.168.1.1'.match(/((\d{1,3})\.){3}(\d{1,3})/)
Py: m = re.search(r'((\d{1,3})\.){3}(\d{1,3})', '192.168.1.1')
m.group(0) # '192.168.1.1'
output
Full match: "192.168.1.1"
Group 1: "1." (last repetition of the outer group)
Group 2: "1" (last repetition of the inner group)
Group 3: "1"
Note When a group is repeated with a quantifier, only the LAST capture is retained. If you need all repetitions, use findall or matchAll instead. Numbering is left-to-right by opening parenthesis.