More handy tools

INPUT · Slides

Pull the pieces out with brackets

01 / 06

Finding it is not enough

Last lesson you learned to find a phone number like 020-7946. But what you actually want is usually what comes after that.

  • just the dialling code
  • a date split into year, month and day
  • the name and the count, separately

This lesson is about the machinery for breaking a match up further.

02 / 06

What you wrap in brackets comes out

Inside the shape, wrap the part you want in ( ). That is the whole of it.

What you wrapped is called a group, and you take it back by number with group(1), group(2) and so on. The numbers run from 1 in the order the opening brackets appear.

import rem = re.search(r"(\d+)-(\d+)", "phone 020-7946")if m:    print(m.group(1))    print(m.group(2))

Result

020
7946

03 / 06

group(0) is the whole match

Number 0 is special: it means everything that matched, brackets or no brackets.

The group() you were writing last lesson was in fact the short form of group(0). That is why the whole thing came back even with no argument.

import rem = re.search(r"(\d+)-(\d+)", "phone 020-7946")if m:    print(m.group(0))    print(m.group())

Result

020-7946
020-7946

04 / 06

Take them all at once with groups()

Writing group(1), group(2), group(3) over and over is tedious. groups() hands back everything you bracketed in one tuple.

It is a tuple, so taking a value apart into separate names, which you met in Chapter 2, works as it stands: year, month, day = m.groups().

import rem = re.search(r"(\d+)-(\d+)-(\d+)", "2026-09-14")if m:    print(m.groups())    year, month, day = m.groups()    print(f"{day}/{month}/{year}")

Result

('2026', '09', '14')
14/09/2026

05 / 06

Groups turn findall into tuples

Hand findall a shape with brackets in it and what comes back changes to a list of tuples.

Each item is split up already, so you can go straight round it with for code, number in .... It is collecting and splitting in one go.

import reprint(re.findall(r"(\d+)-(\d+)", "020-7946 0113-4960"))

Result

[('020', '7946'), ('0113', '4960')]

06 / 06

The checking habit does not change

Groups or no groups, nothing found is still None.

m.group(1) reaches even further in than m.group() does, so forgetting if m: still ends in an AttributeError.

m = re.search(r"(\d+)-(\d+)", text)if m:    print(m.group(1))else:    print("not found")

Adding the else is a kindness: the screen then says that nothing was found. Next lesson we stop looking and start rewriting.