RX

Groups & Alternation

Regular Expressions · 7 entries

Capturing Group ()

syntax
(pattern)  captures the matched text
example
JS:  'Date: 2026-04-04'.match(/(\d{4})-(\d{2})-(\d{2})/)
Py:  m = re.search(r'(\d{4})-(\d{2})-(\d{2})', '2026-04-04')
     m.group(1), m.group(2), m.group(3)
output
JS: ["2026-04-04", "2026", "04", "04"]
Py: ('2026', '04', '04')

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.

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.

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'
output
JS: m.groups => { year: "2026", month: "04", day: "04" }
Py: 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.

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).

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).

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.

Nested Groups

syntax
((inner) outer)  groups inside groups
example
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.