Lessons · Regex · Quick reference
Regex quick reference
77 topics, one line each, in the order Hone teaches them.
Hone is a place to practise programming. This sheet is the whole Regex track at a glance: every idea it covers, in the order they are taught, one line each. It is a map rather than a lesson. Read opens the full explanation of an idea; Practise gives you a question on it. Both are free, and reading needs no account at all.
Regex that reads · Literal to pattern
literal charactersA plain pattern like error finds those exact characters anywhere in the text. Read: Characters match themselves · Practise literal characters
any one characterThe dot matches exactly one character of any kind, except a newline. Read: Any one character · Practise any one character
escaping specialsBackslash before . * + ? ( ) [ ] { } ^ $ | \ makes it a literal character. Read: Literal special characters · Practise escaping specials
character classes[abc] matches one of a, b or c; [a-z] a range; \d \w \s are digits, word characters, whitespace. Read: One character from a set · Practise character classes
\d: any digit\d matches one digit, 0 to 9. \D matches one character that is not a digit. Uppercase is the opposite of lowercase for every such class. Read: Matching a digit · Practise \d: any digit
Regex that reads · How many
+ * ? quantifiersA quantifier says how many of the thing before it: ? is 0 or 1, * is 0 or more, + is 1 or more, {n} exactly n, {n,m} between. Read: How many times · Practise + * ? quantifiers
+: one or more+ means one or more of the token before it. a+ matches a, aa, aaa, and never an empty run. Read: One or more · Practise +: one or more
*: none or more* means zero or more of the token before it, so a* matches the empty string in any text. It is + with 'nothing at all' allowed. Read: Zero or more · Practise *: none or more
?: there or not? after a token or group makes it optional: zero or one of it. colou?r matches color and colour; (ab)?c matches c and abc. Read: Zero or one · Practise ?: there or not
{2,4}: between two counts{n} means exactly n, {n,} at least n, {n,m} between n and m inclusive. \d{3} is three digits; \d{2,4} is two to four. Read: Exactly, at least, between · Practise {2,4}: between two counts
Regex that reads · Where
^ and $ anchors^ matches the start of the text, $ the end. Together they mean 'the whole thing must be this'. Read: Pin the pattern to the edges · Practise ^ and $ anchors
word boundaries\b matches the position between a word character and a non-word one; \bcat\b is the whole word cat. Read: The edge of a word · Practise word boundaries
alternation (or)a|b matches either. Its scope is everything on each side, so group it: gr(a|e)y. Read: This or that · Practise alternation (or)
capture groupsParentheses group a piece of the pattern and remember what it matched, numbered from 1. Read: Capturing the parts · Practise capture groups
( ): keeping the part you matchedParentheses make a group: they let a quantifier apply to several characters at once, and they capture the matched text so you can pull it out afterwards. Read: Capturing a piece · Practise ( ): keeping the part you matched
Regex that reads · The sharp edges
greedy vs lazy* and + match as much as possible; adding ? (.*?) makes them stop at the first chance. Read: Greedy takes all it can · Practise greedy vs lazy
*?: stopping at the first matchA ? after a quantifier makes it lazy: .*? and +? take as few characters as will still let the rest of the pattern match, instead of as many. Read: As little as possible · Practise *?: stopping at the first match
lookaheadx(?=y) matches x only if y comes next, but y is not part of the match. (?!y) is the negative. Read: Check what follows without taking it · Practise lookahead
backreferences\1 matches whatever group 1 captured, so (\w)\1 is a doubled letter. Read: The same thing again · Practise backreferences
catastrophic backtrackingNested quantifiers like (a+)+ can backtrack exponentially on input that almost matches; a server hangs on one request. Read: Patterns that never finish · Practise catastrophic backtracking
The pattern that is right about your data · Which call, and what it hands back
search or match: where it starts lookingmatch anchors the pattern at the very start of the string; search scans forward until it finds one. Read: Where the engine starts looking · Practise search or match: where it starts looking
fullmatch: all of it or nothingfullmatch requires the pattern to account for every character in the string. Read: All of it, or nothing · Practise fullmatch: all of it or nothing
finditer: matches and where they werefinditer hands back a match object per occurrence, each knowing its own position; findall hands back strings and throws the positions away. Read: The matches, and where they were · Practise finditer: matches and where they were
a failed search hands back NoneA search that finds nothing hands back None, and None has no .group(). Read: Nothing is None, not empty · Practise a failed search hands back None
group(0): the whole matchgroup(0) is everything the pattern matched; the numbered groups start at 1 and are counted by their opening brackets, left to right. Read: Zero is the whole match · Practise group(0): the whole match
findall hands back the group, not the matchOnce a pattern has groups, findall returns the groups rather than the match: one tuple per match with more than one group, a plain list with exactly one. Read: findall hands back the group · Practise findall hands back the group, not the match
The pattern that is right about your data · Change the text, not just find it
\1 in the replacementIn the replacement, \1 and \2 stand for what those groups captured. The replacement is not a pattern; it is text with holes in it. Read: Putting the pieces back in a different order · Practise \1 in the replacement
replacing with a functionGive sub a function instead of a string and it is handed the match, and whatever it returns is used. Read: A replacement that decides · Practise replacing with a function
replacing only the first fewcount caps how many are replaced, from the left; subn hands back the result and the number together. Read: Only the first few, and how many there were · Practise replacing only the first few
split: keeping the separatorA capturing group in the split pattern puts the separator into the result; without the brackets it is thrown away. Read: Splitting, and keeping what you split on · Practise split: keeping the separator
The pattern that is right about your data · A flag changes the whole meaning
^ and $: once, or once per lineWithout MULTILINE, ^ means the start of the STRING. With it, ^ also matches just after every newline -- and $ moves with it. Read: One start, or one per line · Practise ^ and $: once, or once per line
the dot stops at a newlineThe dot means any character except a newline, unless you turn on DOTALL. Read: The dot stops at a newline · Practise the dot stops at a newline
VERBOSE: a pattern with room to breatheUnder VERBOSE, whitespace in the pattern is ignored and # starts a comment, so a long pattern can be laid out with a note on each part. Read: A pattern with room to breathe · Practise VERBOSE: a pattern with room to breathe
(?i): a flag inside the pattern(?i) at the front turns on case-insensitive matching for the whole pattern; (?i:...) turns it on for just that group. Read: A flag written inside the pattern · Practise (?i): a flag inside the pattern
$ and \Z: two different ends$ matches at the end of the string AND just before a newline at the end of it. \Z matches only the very end. Read: Two different ends · Practise $ and \Z: two different ends
The pattern that is right about your data · The data is not ASCII
\w is not only EnglishIn Python 3, \w means a letter in any script, plus digits and the underscore. [a-z] means twenty-six ASCII characters and nothing else. Read: A letter is not always a-z · Practise \w is not only English
\d is more digits than you think\d means any Unicode decimal digit, which includes scripts other than this one. [0-9] means exactly those ten characters. Read: More digits than you think · Practise \d is more digits than you think
ASCII: back to a-z and 0-9re.A makes \w, \d, \s and \b mean their ASCII-only versions, across the whole pattern. Read: Narrowing it back to ASCII · Practise ASCII: back to a-z and 0-9
matching bytes rather than textA bytes pattern matches bytes and a str pattern matches str; re refuses to mix them, and in bytes mode \w is ASCII-only. Read: Bytes are not text · Practise matching bytes rather than text
The pattern that is right about your data · Fast, or hanging
a quantifier inside a quantifier(a+)+b lets the same characters be divided between the repetitions in many ways, and on a string that does not match, the engine tries all of them. Read: A quantifier inside a quantifier · Practise a quantifier inside a quantifier
anchoring so it gives up earlyUnanchored, a failed match is retried from position 1, then 2, then 3, to the end of the line. Anchored, there is one starting position. Read: Telling the engine where to start · Practise anchoring so it gives up early
the pattern cache, and when it stops helpingThe module-level calls look the compiled pattern up in a cache, so the usual advice to compile is about clarity, not about a large hidden cost. Read: Compiling, and what it is really for · Practise the pattern cache, and when it stops helping
which alternative winsAlternation takes the FIRST alternative that matches at the earliest position, not the longest one. Read: The first branch that works, wins · Practise which alternative wins
The pattern that is right about your data · When not to reach for one
why not to parse HTML with oneAttributes in any order, unclosed tags, comments, script bodies containing '<', and tags inside tags: a pattern handles the page you tested and not the page you get. Read: HTML nests and a pattern cannot count · Practise why not to parse HTML with one
the comma inside the quotesA CSV field may hold a comma of its own inside quotes, so splitting a line on commas gives the wrong number of fields. Read: The comma inside the quotes · Practise the comma inside the quotes
an address you validate by sending to itThe real grammar for an email address is enormous, so a strict pattern refuses valid addresses -- and the only proof one works is that mail arrives. Read: An address you validate by sending to it · Practise an address you validate by sending to it
a pattern cannot count bracketsA regular expression has no memory of how deep it currently is, so it cannot match balanced brackets to any depth. Read: It can find them; it cannot pair them · Practise a pattern cannot count brackets
The pattern that is right about your data · Prove the pattern
testing it on what nearly matchesAnything obviously right passes a pattern that is far too loose. The near miss is where the boundary actually is, and a boundary is what a pattern is. Read: Test it on what nearly matches · Practise testing it on what nearly matches
a match that is not the whole valueA search that succeeds says the pattern OCCURS somewhere. It never says the value is that thing. Read: A match that is not the whole value · Practise a match that is not the whole value
re.escape: anything a person typedre.escape backslashes every character that could be special, so the result matches the text and nothing else. Read: What a person typed is not a pattern · Practise re.escape: anything a person typed
the pattern you will have to read againVERBOSE for a comment on each part, named groups so the code reads by meaning rather than by position. Read: The pattern you will have to read again · Practise the pattern you will have to read again
More
^: the startQuestions on Hone; no lesson yet. Practise ^: the start
[a-c]: a rangeQuestions on Hone; no lesson yet. Practise [a-c]: a range
compiling a pattern onceQuestions on Hone; no lesson yet. Practise compiling a pattern once
$: the endQuestions on Hone; no lesson yet. Practise $: the end
DOTALL: the dot takes newlines tooQuestions on Hone; no lesson yet. Practise DOTALL: the dot takes newlines too
\. a literal dotQuestions on Hone; no lesson yet. Practise \. a literal dot
findall: every matchQuestions on Hone; no lesson yet. Practise findall: every match
findall with groupsQuestions on Hone; no lesson yet. Practise findall with groups
flags: i, m, s and xi ignores case, m makes ^ and $ match on every line, s lets the dot take newlines, x gives the pattern room to breathe. A flag applies to the WHOLE pattern. Read: Switches on the whole pattern · Practise flags: i, m, s and x
anchored at both endsQuestions on Hone; no lesson yet. Practise anchored at both ends
IGNORECASEQuestions on Hone; no lesson yet. Practise IGNORECASE
(?<=...): what comes beforeQuestions on Hone; no lesson yet. Practise (?<=...): what comes before
match starts at the beginningQuestions on Hone; no lesson yet. Practise match starts at the beginning
what a match hands backQuestions on Hone; no lesson yet. Practise what a match hands back
MULTILINE: every line's startQuestions on Hone; no lesson yet. Practise MULTILINE: every line's start
reading a named groupQuestions on Hone; no lesson yet. Practise reading a named group
(?P<name>...): naming a groupQuestions on Hone; no lesson yet. Practise (?P<name>...): naming a group
[^0-9]: anything butQuestions on Hone; no lesson yet. Practise [^0-9]: anything but
(?:...) groups without keepingQuestions on Hone; no lesson yet. Practise (?:...) groups without keeping
grouping without capturingQuestions on Hone; no lesson yet. Practise grouping without capturing
search finds nothingQuestions on Hone; no lesson yet. Practise search finds nothing
splitting on a patternQuestions on Hone; no lesson yet. Practise splitting on a pattern
sub: replacing what matchedQuestions on Hone; no lesson yet. Practise sub: replacing what matched
\s: any spaceQuestions on Hone; no lesson yet. Practise \s: any space
\b: the edge of a wordQuestions on Hone; no lesson yet. Practise \b: the edge of a word
\w: a word characterQuestions on Hone; no lesson yet. Practise \w: a word character