A regular expression describes a pattern of text. re.findall(pattern, text) returns every match as a list, and re.search(pattern, text) returns the first match or None.
The building blocks: \d a digit, \w a letter, digit or underscore, \s whitespace, . any character, [A-Z] one character from a set. Repeat with + (one or more), * (zero or more), ? (optional) and {3} or {2,4} (a count). ^ and $ anchor the start and end, and \b a word boundary.
Write patterns as raw strings, r"\d+", so Python leaves the backslashes alone. Characters with a meaning, like ., $, ( and [, need a backslash to match literally: r"v2\.1".
+ and * are greedy: they match as much as they can. Add ? (.*?) for the shortest match.