Ctrl K

Regex Basics: Patterns You Will Actually Use

beginner TheToolSera Team 8 min read Updated 20 May 2026

Regular expressions look cryptic because they are dense, not because they are complicated. A dozen constructs cover the overwhelming majority of real work, and learning those is an afternoon well spent.

The core building blocks

PatternMatchesExample
.Any character except newlinea.c matches abc, a7c
\d \w \sDigit, word character, whitespace\d\d matches 42
\D \W \SThe negation of each\S+ matches a run of non-space
[abc]Any one listed character[aeiou] matches a vowel
[^abc]Any character not listed[^0-9] matches a non-digit
[a-z0-9]A rangeLowercase letters and digits
|Alternationcat|dog

Quantifiers

  • * — zero or more
  • + — one or more
  • ? — zero or one (optional)
  • {3} — exactly three
  • {2,5} — between two and five
  • {2,} — two or more

Anchors and boundaries

^ matches the start of the string, $ the end, and \b a word boundary. Anchors are the usual fix when a pattern matches something inside a longer string that you did not intend.

/cat/.test("concatenate");        // true  — substring match
/\bcat\b/.test("concatenate");    // false — word boundary
/^\d{4}$/.test("2026");            // true  — exactly four digits

Greedy vs lazy

Quantifiers are greedy by default: they take as much as possible and give characters back only if the rest of the pattern fails. Adding ? makes them lazy, taking as little as possible.

Greedy — matches the whole line
/<.+>/.exec("<b>bold</b>")
// "<b>bold</b>"
Lazy — matches one tag
/<.+?>/.exec("<b>bold</b>")
// "<b>"

Groups and captures

Named groups make replacements readable
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const { groups } = re.exec("2026-06-02");
groups.year;  // "2026"

"2026-06-02".replace(re, "$<day>/$<month>/$<year>");
// "02/06/2026"

// (?:...) groups without capturing — useful with alternation
/(?:https?|ftp):\/\//.test("https://x.com"); // true

Flags

  • g — find all matches, not just the first
  • i — case insensitive
  • m — ^ and $ match at each line break
  • s — . also matches newlines
  • u — full Unicode support, required for \p{...} property escapes

Regex Tester

Test patterns with live highlighting, capture groups and a replace preview.

Try Regex Tester

Patterns worth keeping

/^\s+|\s+$/g            // leading/trailing whitespace
/\s{2,}/g                // runs of whitespace to collapse
/^#?([0-9a-f]{6}|[0-9a-f]{3})$/i   // hex colour
/^\+?[0-9 ()-]{7,}$/     // loose phone check
/(\w+)\s+\1/gi           // a repeated word (backreference)

Common mistakes

Parsing HTML with regex

Nested and optional structures are beyond regular grammar. Use a DOM parser.

Chasing a perfect email regex

The full RFC grammar is unusable in practice. Check for one @ with text on both sides, then verify by sending a message.

Catastrophic backtracking

Nested quantifiers like (a+)+ can hang on crafted input. Avoid nesting, and anchor patterns where possible.

Reusing a /g regex object

lastIndex persists between calls, so alternate calls appear to fail. Create a fresh regex or reset lastIndex.

Forgetting to escape metacharacters

A literal dot is \. — an unescaped one matches any character.

Write the pattern incrementally against real sample data, adding one construct at a time. A tester with live highlighting turns this into seconds per iteration.

Frequently asked questions

What is the difference between * and +?

* allows zero repetitions, + requires at least one. Using * where + was intended is a very common cause of unexpected empty matches.

Why does my regex match more than expected?

Quantifiers are greedy. Add ? to make them lazy, or use a negated character class such as [^>]+ instead of .+

Are regex flavours the same everywhere?

Mostly, but lookbehind, named groups and Unicode property escapes vary between JavaScript, PCRE, Python, Go and POSIX tools.

How do I match across multiple lines?

Use the s flag so . matches newlines, and the m flag if you want ^ and $ to apply at each line break.

Put this into practice

Regex Tester runs entirely in your browser — no upload, no account, no limits.

Open Regex Tester

Related tools

Related guides

All guides

Explore related topics