All subjects · Computer Science · WCP04 Advanced Practical Programming and Problem-solving

Regular expressions: finding and validating text

Edexcel IAL Computer Science · WCP04 Advanced Practical Programming and Problem-solving

A regular expression (regex) is a pattern that describes text. With Python's `re` module you can find every phone number in a document, or check that a date is in the right format, in one line.

Practise this in the app: instant marking and a fix for every mistake. Free, no email needed to start.

Practise this lesson

The building blocks

PatternMatches
`.`any character except newline
`\d` / `\D`a digit / a non-digit
`\w` / `\W`a word character (letter, digit, underscore) / anything else
`\s` / `\S`whitespace / non-whitespace
`[abc]`, `[a-z]`, `[A-Z0-9]`one character from the set or range
`[0-9]`one character NOT in the set
`*` `+` `?`0 or more, 1 or more, 0 or 1 of the item before
`{3}` `{2,4}`exactly 3, from 2 to 4 of the item before
`a|b`a or b
`( )`a group
the caret and `$`start and end of the string
`\b`a word boundary
`\.`a literal full stop (a backslash escapes a metacharacter)

The re functions

Write patterns as raw strings, r"...", so Python does not treat the backslashes itself.

import re
text = "Order 66 shipped 12-03-25; order 7 shipped 01-04-25."
print(re.findall(r"\d+", text))
m = re.search(r"\d\d-\d\d-\d\d", text)
print(m.group(), m.start(), m.end())
print(re.sub(r"\d", "#", "PIN 4821"))
print(re.split(r"[,;]\s*", "red, green;blue"))

Output:

['66', '12', '03', '25', '7', '01', '04', '25']
12-03-25 17 25
PIN ####
['red', 'green', 'blue']

Validating input

Build validation patterns from small, tested parts. A day from 01 to 31 is: 0 then 1 to 9, or 1 or 2 then any digit, or 3 then 0 or 1. With fullmatch, nothing extra is allowed before or after.

import re
DAY = r"(0[1-9]|[12][0-9]|3[01])"
MONTH = r"(0[1-9]|1[0-2])"
DATE = DAY + "-" + MONTH + r"-\d{2}"
for d in ["07-11-26", "31-12-25", "32-01-25", "7-11-26"]:
    print(d, re.fullmatch(DATE, d) is not None)

Output:

07-11-26 True
31-12-25 True
32-01-25 False
7-11-26 False

A regex checks format only: '31-02-25' passes the pattern even though 31 February does not exist. Check ranges and real dates in code if needed. The sample mark scheme gives no credit for a day pattern that simply lists 01|02|...|31: build it from character classes as above.

What the PLS lists, and how Python writes it

import re
PIN = r"\A\d{4}\Z"
for pin in ["1234", "12345", "1234\n"]:
    print(repr(pin), re.search(PIN, pin) is not None, re.search(r"^\d{4}$", pin) is not None)
m = re.search(r"\d+", "Room 101")
print(m.start(), m.end(), callable(m.start))

Output:

'1234' True True
'12345' False False
'1234\n' False True
5 8 True

Worked example

Extract every UK-style postcode area code (one or two capital letters followed by one or two digits, as a whole word) from a sentence.

  1. ```python import re s = "Depots in M1, LS12 and EH3, not in 12AB." print(re.findall(r"\b[A-Z]{1,2}\d{1,2}\b", s)) ```
  2. Output: ``` ['M1', 'LS12', 'EH3'] ```

Answer: `[A-Z]{1,2}` then `\d{1,2}`, wrapped in word boundaries so '12AB' does not match.

Key idea: Raw strings; \d \w \s, [sets], * + ? {m,n}, | and groups; search finds the first match, fullmatch validates, findall lists, sub replaces, split splits; Match.group(), start(), end().

Check yourself

  1. What does this program print? ```python import re print(re.findall(r"\d+", "3 cats, 12 dogs, 150 fish")) ```
    Show answer

    ['3', '12', '150']. `\d+` matches each run of digits. Output: `['3', '12', '150']`

  2. What does this program print? ```python import re m = re.search(r"[A-Z]\d", "abc X9 Y7") print(m.group(), m.start()) ```
    Show answer

    X9 4. The first capital letter followed by a digit is X9, starting at index 4 (a=0, b=1, c=2, space=3). Output: `X9 4`

  3. What does this program print? ```python import re for s in ["AB123", "AB12", "ab123"]: print(re.fullmatch(r"[A-Z]{2}\d{3}", s) is not None, end=" ") ```
    Show answer

    True False False. Only AB123 has exactly two capitals then three digits. Output: `True False False`

  4. What does this program print? ```python import re print(re.sub(r"\s+", " ", "too many spaces")) ```
    Show answer

    too many spaces. Every run of whitespace is replaced by one space. Output: `too many spaces`

  5. What does this program print? ```python import re print(re.split(r"\d", "a1b22c")) ```
    Show answer

    ['a', 'b', '', 'c']. Splitting on each digit gives 'a', 'b', an empty string between the two 2s, and 'c'. Output: `['a', 'b', '', 'c']`

  6. Which function should validate that a whole input string is a 4-digit PIN?
    • `re.search(r"\d{4}", pin)`
    • `re.findall(r"\d", pin)`
    • `re.fullmatch(r"\d{4}", pin)`
    • `re.match(r"\d", pin)`
    Show answer

    `re.fullmatch(r"\d{4}", pin)`. fullmatch requires the entire string to be exactly four digits.

  7. Which pattern matches a two-digit month from 01 to 12 and nothing else (with fullmatch)?
    • `0[1-9]|1[0-2]`
    • `[0-1][0-9]`
    • `\d{2}`
    • `[1-12]`
    Show answer

    `0[1-9]|1[0-2]`. 0 followed by 1 to 9, or 1 followed by 0, 1 or 2.

  8. What does this program print? ```python import re print(re.findall(r"(\w+)@", "ana@x.com, bo@y.org")) ```
    Show answer

    ['ana', 'bo']. With one group, findall returns just the group's text: the names before each @. Output: `['ana', 'bo']`

Practise with instant feedback

Sources

Last updated 8 November 2026. Spotted a mistake? Tell us.