The regex . matches any character, including the dot itself. So the pattern a.c matches "abc", "a5c", and "a-c" โ not just the literal "a.c" you probably meant. That one surprise trips up more beginners than anything else, because the character that looks most harmless is secretly a wildcard.
A regular expression is a pattern for matching text. Instead of searching for an exact word, you describe the shape of what you want โ three digits, then a dash, then four digits โ and the engine finds every string that fits. It looks like line noise at first. But almost all real-world regex uses about a dozen tokens, and once those click, the rest is just combining them.
The tokens that do 80% of the work
Learn these nine and you can read most patterns you'll meet:
\dโ a single digit, 0 through 9.\d\d\dmatches "007".\wโ a "word" character: a letter, a digit, or an underscore. It does not include spaces or hyphens, which surprises people..โ any single character except a line break (the wildcard from above).*โ the preceding item, zero or more times.\d*matches "", "5", or "500000".+โ one or more times.\d+needs at least one digit to match.?โ zero or one; it makes the thing before it optional.colou?rmatches both "color" and "colour".^and$โ anchors.^marks the start of the string,$the end.^\d+$means "digits, and nothing else."[abc]โ a character class: match any one character inside the brackets.[aeiou]is a single vowel; ranges like[a-z]and[0-9]work too. Put^first and it flips:[^0-9]means "any character that is not a digit."|โ or.cat|dogmatches "cat" or "dog".
One more shorthand worth adding: {n} means "exactly n times," so \d{4} is four digits. That's the whole starter vocabulary. Everything below is just these pieces stacked together.
Pattern 1: a rough email check
^\S+@\S+\.\S+$
Read it left to right. \S is "any non-space character" (the opposite of \s). So this says: start, one or more non-space characters, an @, more non-space characters, a literal dot โ note the backslash, which turns the wildcard . back into a plain dot โ then more non-space characters, end.
It accepts "sam@example.com" and rejects "sam@ example" and "no-at-sign.com". It's called rough on purpose: it also happily accepts "x@x.x". That's fine for catching typos in a form. It is not real validation, which matters later.
Pattern 2: digits only
^\d+$
The anchors are the entire point here. Without them, \d+ matches "abc123def" โ because the engine finds the "123" sitting inside the string and calls that a match. Regex matches partial strings by default. Wrapping the pattern in ^ and $ forces it to describe the whole string, so "abc123" now fails and only "123" passes. Any time you mean "this and only this," reach for the anchors. Forgetting them is the second most common beginner bug, right after the unescaped dot.
Pattern 3: find and replace with groups
Say you have dates like "2026-09-12" and you want "09/12/2026". Parentheses capture pieces you can reuse.
- Find:
(\d{4})-(\d{2})-(\d{2}) - Replace:
$2/$3/$1
The three parenthesized groups capture the year, month, and day. In the replacement, $1 is whatever the first group matched, $2 the second, and so on. So you're saying: put the month, then the day, then the year, rejoined with slashes. Run it across a thousand rows and every date flips instantly. This is where regex earns its keep โ not matching, but restructuring text in bulk. (Some tools write the backreference as \1 instead of $1; check which yours uses.)
The one rule that saves you: test on real samples
Never trust a regex you haven't run against actual data โ both the strings you want to match and the ones you don't. Regex fails quietly. It won't throw an error; it will just match the wrong things and hand you a result that looks plausible. The unescaped-dot bug and the missing-anchors bug both produce output that seems fine until a bad row slips through weeks later.
Paste your pattern and a dozen real lines into a live tester and watch what highlights. The Regex Tester on everyboringtool.com does this in the browser โ it highlights matches as you type, shows your capture groups, and never uploads your text anywhere, which matters when the "real samples" are customer records or logs. Feed it the ugly cases first: the empty string, the one with a trailing space, the one that's almost right. If it survives those, trust it.
When regex is the wrong tool
Regex is a pattern matcher, not a parser, and a few jobs will punish you for forgetting that:
- Nested structures like HTML or JSON. Regex can't count how deep it is inside nested tags, so it can't reliably match a
<div>to its closing tag. Use a real parser. For JSON specifically, a JSON Formatter will do more, faster. - True email validation. The official spec is genuinely enormous, and even a perfect pattern can't tell you the address exists. The only real check is sending a confirmation email. Use the rough pattern for typos and stop there.
- Simple contains-checks. If you just need "does this line have the word error in it," a plain
includes()or Ctrl-F beats a regex on both speed and readability. - Catastrophic backtracking. Patterns with nested quantifiers like
(a+)+can take exponential time on certain inputs and hang your program. If a regex is mysteriously slow, this is usually why.
The honest summary: regex is unbeatable for finding and reshaping flat, predictable text patterns, and a trap for structured or open-ended ones.
Start with \d, ., +, ?, the ^ $ anchors, [ ], and |. Write the smallest pattern that matches your real examples, wrap it in anchors when you mean the whole string, and test it against your ugliest inputs before you ship it. That's the working 20%.