Python Arena
Step 1 of 4

What regular expressions are

String methods find exact text: "cat" in text or text.find("cat"). But often you're looking for a kind of text: any number, a time of day, a word with a capital letter. A regular expression (a regex for short) describes such text with a pattern. Regular expressions are a small language of their own, and the same patterns work, with small differences, in most programming languages and in many text editors.

Python's regular expressions are in the module re. The function re.search(pattern, text) looks for the first place in the text that matches the pattern:

import re

notes = ["Meeting at 10", "Lunch with Pia", "Dentist at 3 pm"]
for note in notes:
    if re.search(r"\d", note):
        print("Has a time:", note)
Output
Has a time: Meeting at 10
Has a time: Dentist at 3 pm

In a pattern, most characters simply match themselves: the pattern r"Pia" matches the text Pia, with the same capitals. A few have a special meaning. \d matches any one digit, 0 to 9.

re.search returns a match object when it finds a match, and None when it doesn't. In an if, a match counts as true and None as false. The match object's method group() gives the text that matched:

In the Python interpreter
>>> import re
>>> re.search(r"\d", "Room 42")
<re.Match object; span=(5, 6), match='4'>
>>> re.search(r"\d\d", "Room 42").group()
'42'
>>> print(re.search(r"\d", "Room B"))
None
>>> re.search(r"\d", "Room 42") is not None
True

span=(5, 6) says where the match is: from index 5 up to index 6. When a function should return True or False, compare the result with None, as the last line does.

Raw strings

The patterns above are written r"...". The r makes a raw string, in which Python leaves every backslash as it is. In an ordinary string, Python reads some backslash pairs itself: "\n" is a line break and "\t" a tab. Patterns are full of backslashes, so write them as raw strings, and the re module gets exactly what you typed:

In the Python interpreter
>>> len("\n")
1
>>> len(r"\n")
2
>>> print(r"\d and \n")
\d and \n

Without the r, Python even warns about a pattern such as "\d": SyntaxWarning: "\d" is an invalid escape sequence.

Finding every match

re.findall(pattern, text) returns a list of all the matches, as strings. A + after a part of a pattern means "one or more of it" (step 3 shows more marks like it), so \d+ matches a whole run of digits: a number.

import re

text = "3 apples, 12 pears and 150 grapes"
print(re.findall(r"\d", text))
print(re.findall(r"\d+", text))
numbers = [int(number) for number in re.findall(r"\d+", text)]
print(sum(numbers))
Output
['3', '1', '2', '1', '5', '0']
['3', '12', '150']
165

The matches are strings, so turn them into numbers with int before you calculate with them.

Your task

Challenge 1 of 3

A password needs at least one digit. Fill in the two blanks: the name of the re function that looks for a match, and the pattern for one digit. The program should print:

sunshine needs a digit
sunsh1ne ok
2fast ok

Challenge 2

What does this program print? Type each line it prints.

Challenge 3

Write a function numbers_in(text) that returns a list of the whole numbers in the text, as integers, in the order they appear. Use the re module. For example,

print(numbers_in("Gate 7 opens at 1930, row 12"))

should print:

[7, 1930, 12]