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)
Has a time: Meeting at 10
Has a time: Dentist at 3 pmIn 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:
>>> 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
Truespan=(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:
>>> len("\n")
1
>>> len(r"\n")
2
>>> print(r"\d and \n")
\d and \nWithout 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))
['3', '1', '2', '1', '5', '0']
['3', '12', '150']
165The matches are strings, so turn them into numbers with int before you calculate with them.