Regex basics: anchors, quantifiers, and common mistakes

Most regex bugs come from four things: greedy quantifiers, missing anchors, unescaped special characters, and forgetting a pattern matches anywhere by default.

A regular expression describes a pattern to search for in text, not a fixed string. `cat` matches the letters c-a-t anywhere in a larger string -- inside 'concatenate' too -- unless you tell it otherwise. Most beginner regex bugs come from forgetting that default: the pattern matches anywhere it can, not the whole string, unless anchored.

Anchoring a pattern

`^` matches the start of a string (or line, depending on mode) and `$` matches the end. `^cat$` matches a string that is exactly 'cat' and nothing else, while `cat` alone matches 'cat' anywhere, including inside longer words. Forgetting anchors is one of the most common reasons a validation regex is 'too permissive' and accepts input it shouldn't.

Greedy vs. lazy quantifiers

`*`, `+`, and `{n,m}` are quantifiers -- they say how many times the preceding token can repeat. By default they are greedy: they match as much text as possible, then backtrack only if needed. This is why `<.*>` against `<a><b>` matches the whole string from the first `<` to the last `>`, not just `<a>` -- a lazy quantifier (`<.*?>`) matches as little as possible instead and stops at the first `>`.

Confusing greedy and lazy matching is the single most common source of 'my regex matched way more than I expected' bugs.

Escaping special characters

Characters like `.`, `*`, `+`, `(`, `)`, and `$` have special meaning in regex. To match them literally -- a literal period in a domain name, for example -- they need to be escaped with a backslash (`\.`). Forgetting this is why a naive email or domain pattern often matches more than intended: an unescaped `.` matches any character, not just a literal dot. The regex escape tool handles this automatically for a literal string you want to search for exactly.