← Python lessons

Python Regex Character Classes, Anchors and re.fullmatch

A character class such as [aeiou] matches any one character from a set. Anchors such as ^ and $ pin a pattern to the start or end of the text.

Read Regex basics first.

Match one character from a set with [ ]

Put the allowed characters inside square brackets. A dash makes a range: [a-z], [0-9] or [A-Za-z]. A ^ just inside the bracket means "any character except these".

import re

print(re.findall(r"[aeiou]", "regular expression"))
print(re.findall(r"[A-Z][a-z]+", "Ada met Ben in Paris"))
print(re.findall(r"[^0-9 ]+", "R2 D2 and C3PO"))

[A-Z][a-z]+ is one capital letter, then one or more lowercase letters. [^0-9 ]+ is a run of characters that are not digits or spaces.

Anchor to the start or end with ^ and $

Outside square brackets, ^ means "the start of the string" and $ means "the end of the string".

import re

files = ["game.py", "notes.txt", "py_test.md"]
for name in files:
    if re.search(r"\.py$", name):
        print(name, "ends with .py")
    if re.search(r"^py", name):
        print(name, "starts with py")

\. is a real dot. Without the $, \.py would also match my.python.txt.

Match whole words with \b

\b is a word boundary: the edge between a word character and anything else. It matches a position, not a character.

import re

text = "cat, concat, cats and a cat."
print(re.findall(r"cat", text))
print(re.findall(r"\bcat\b", text))

The plain pattern finds cat inside concat and cats too. With \b on both sides, only the two whole words match.

Check the whole string with re.fullmatch

re.search() finds a match anywhere in the string. re.fullmatch() matches only when the whole string fits. Use it to check input, such as a PIN.

import re

for pin in ["1234", "12345", "12a4"]:
    found = bool(re.search(r"\d{4}", pin))
    whole = bool(re.fullmatch(r"\d{4}", pin))
    print(pin, found, whole)

bool() turns a match into True and None into False. "12345" holds four digits, but it is not four digits, so re.fullmatch() says no.

Note: {3,10} means "between 3 and 10 times". [a-z]{3,10} matches 3 to 10 lowercase letters.

See also: Data validation, Groups and re.sub.

Your turn

A username is valid when it has 3 to 10 characters, and each one is a lowercase letter or a digit. Print each name with True or False.

import re

names = ["ada99", "Bo", "cy_7", "dev"]
for name in names:
    # add one line: print the name and whether re.fullmatch() accepts it
    pass

Expected output

ada99 True
Bo False
cy_7 False
dev True

Practise this in the free Python course, where every exercise checks your code instantly.