C.W.K.
Stream
Lesson 10 of 12 · published

Groups in Replacement

~8 min · substitution, replacement, sed

Level 0Pattern-Curious
0 XP0/90 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

Refer to captured groups in your replacement string

Substitution (re.sub, sed s/old/new/, str.replace_all with regex) lets you reference captured groups in the replacement.

  • Python re.sub: \1, \2, or \g<name> for named groups
  • JavaScript replace: $1, $2, or $<name>
  • sed: \1, \2
  • ripgrep --replace: $1, $2 or $name

The classic use: format conversion

Convert 2026-05-04 to 05/04/2026: re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', text).

The capture groups are reordered in the replacement. This is how regex earns its keep in code mods, log reformatting, CSV-to-CSV transformation.

The 'whole match' reference

Group 0 is the entire match. Useful for wrapping: re.sub(r'\d+', r'[\g<0>]', text) wraps every number in brackets without you having to capture it explicitly. JavaScript: $&; sed: &.

Function as replacement

For complex replacements, most languages let you pass a function instead of a string. Python: re.sub(pattern, callable, text). The callable receives a Match object and returns a string. This unlocks dynamic logic — uppercasing, lookups, conditional rewrites — that pure replacement strings can't express.

Code

Replacement patterns·python
import re

# Reorder date pieces
re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', '2026-05-04 was today')
# '05/04/2026 was today'

# Named replacement
pattern = r'(?P<year>\d{4})-(?P<month>\d{2})'
re.sub(pattern, r'\g<month>/\g<year>', '2026-05')
# '05/2026'

# Wrap with whole match
re.sub(r'\d+', r'[\g<0>]', 'order 1138 of 9999')
# 'order [1138] of [9999]'

# Function as replacement — uppercase all matches
re.sub(r'\b\w+\b', lambda m: m.group().upper(), 'hello world')
# 'HELLO WORLD'

# Function with logic
def shorten(m):
    n = int(m.group(1))
    return 'small' if n < 10 else 'large'
re.sub(r'(\d+)', shorten, 'order 5 and 50')
# 'order small and large'

External links

Exercise

Take a CSV-like file with a column you want to reformat (date, name 'Last, First' → 'First Last', whatever). Write one re.sub that performs the transformation. Run it. The whole file should rewrite in one line.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.