Character classes and anchors are the vocabulary of every pattern you'll write.
Single-character building blocks:
.matches any character except a newline.[abc]matches one of the listed characters; ranges like[a-z0-9]work;[^abc]matches anything except them. Inside brackets most specials lose their meaning, so[.]is a literal dot.- Shorthands:
\da digit,\wa word character (letter, digit or underscore),\swhitespace. Their uppercase versions\D,\W,\Sare the negations. - Escape a special character with a backslash to match it literally:
\.\$\(.
Anchors match a position, not a character:
^the start of the string,$the end.\ba word boundary: between a word character and a non-word character.r"\bcat\b"matches "cat" but not "category".\Aand\Zare the absolute start and end.
A subtle point: $ also matches just before a trailing newline, so re.search(r"^\d+$", "123\n") succeeds. When validating input, use re.fullmatch or end with \Z.
In str patterns, \d and \w are Unicode-aware: \d also matches Arabic-Indic digits, and \w matches letters like é or 東. Use [0-9] when you mean ASCII digits only.
Example
import re
print(re.findall(r"\bcat\b", "cat category bobcat cat.")) # ['cat', 'cat']
print(re.findall(r"[aeiou]", "regex")) # ['e', 'e']
print(re.findall(r"[^a-z ]", "abc D3f!")) # ['D', '3', '!']
print(re.findall(r"\d\.\d", "v1.2 or 3x4")) # ['1.2']
print(re.findall(r"\s", "a b\tc")) # [' ', '\t']
print(bool(re.search(r"^\d+$", "123\n"))) # True: $ before final \n
print(bool(re.fullmatch(r"\d+", "123\n"))) # False
print(bool(re.fullmatch(r"\d+", "١٢٣"))) # True: Unicode digits
print(bool(re.fullmatch(r"[0-9]+", "١٢٣"))) # FalseRemember
[...]matches one character from a set;[^...]negates it\d \w \sare Unicode-aware in str patterns; use[0-9]for ASCII digits$matches before a trailing newline; validate with fullmatch or\Z
Watch out for
- Writing
.to mean a literal dot, e.g.r'example.com'also matches 'exampleXcom'.