Toolmingo
Guides6 min read

How to Use Regular Expressions: A Practical Beginner's Guide

Learn regular expressions from scratch: what regex is, how patterns work, the most useful syntax with examples, common pitfalls, and how to test regex free in your browser.

Regular expressions are one of those tools that look intimidating at first — a line like ^[\w.+-]+@[\w-]+\.[\w.]{2,}$ is not exactly welcoming — but once you understand the building blocks, regex becomes one of the most powerful text-processing tools available to you. This guide starts from zero and builds up to patterns you can actually use.

What is a regular expression?

A regular expression (regex or regexp) is a sequence of characters that defines a search pattern. Instead of searching for an exact string like "cat", you describe a pattern: "any string that starts with a letter, has three characters, and ends with 't'".

Regex is supported in nearly every programming language and text editor. The syntax has minor variations across implementations, but the core concepts are universal.

The simplest patterns: literal characters

The most basic regex is a literal string. The pattern cat matches the exact characters c, a, t in sequence. In the text "I have a cat and a catalog", it matches twice — once in "cat" and once in "catalog".

This is already useful for search-and-replace, but regex becomes powerful when you use special characters to describe classes of characters and repetition.

Character classes: match a set of characters

A character class (written in square brackets [ ]) matches any single character from the set.

Pattern Matches
[aeiou] Any single vowel
[a-z] Any lowercase letter a through z
[A-Z] Any uppercase letter
[0-9] Any digit
[a-zA-Z] Any letter (upper or lower)
[^aeiou] Any character that is NOT a vowel (^ inside [ ] negates)

Shorthand character classes are so common they have their own notation:

Shorthand Equivalent Meaning
\d [0-9] Any digit
\w [a-zA-Z0-9_] Any word character (letter, digit, underscore)
\s [ \t\n\r] Any whitespace character
\D [^0-9] Any non-digit
\W [^\w] Any non-word character
\S [^\s] Any non-whitespace

The . (dot) is a special pattern that matches any character except a newline.

Quantifiers: how many times

After a character or group, you can specify how many times it should appear:

Quantifier Meaning
? 0 or 1 (optional)
* 0 or more
+ 1 or more
{3} Exactly 3
{2,5} Between 2 and 5
{2,} 2 or more

Examples:

  • colou?r matches "color" and "colour" (the u is optional)
  • \d+ matches one or more digits: "7", "42", "12345"
  • \w{3} matches exactly three word characters: "cat", "dog", "a1b"
  • [A-Z]\d{2} matches an uppercase letter followed by exactly two digits: "A42", "Z99"

Anchors: position in the string

Anchors don't match characters — they match positions.

Anchor Matches
^ Start of the string (or line in multiline mode)
$ End of the string (or line in multiline mode)
\b Word boundary (between a \w and a \W character)

Examples:

  • ^hello matches "hello world" but not "say hello"
  • world$ matches "hello world" but not "worldwide"
  • \bcat\b matches "my cat" and "the cat" but not "catalog" or "concatenate"

Groups and alternation

Parentheses ( ) group parts of a pattern together. This lets you apply a quantifier to a whole group:

  • (ha)+ matches "ha", "haha", "hahaha"
  • (ab|cd)+ matches one or more occurrences of "ab" or "cd"

The | character means "or": cat|dog matches "cat" or "dog".

Capture groups also let you extract the matched text. In most languages, after a match, you can retrieve the text matched by each parenthesized group. For example, (\d{4})-(\d{2})-(\d{2}) applied to "2026-07-12" gives you group 1 = "2026", group 2 = "07", group 3 = "12".

Use (?:...) for a non-capturing group when you want the grouping but don't need to capture the content.

Practical regex patterns you can use today

Email address (basic)

[\w.+-]+@[\w-]+\.[\w.]{2,}

Matches most common email formats. Note: truly validating email requires the full RFC 5322 spec, which is extremely complex. For most purposes, this is close enough.

URL (simple)

https?://[\w.-]+(?:\.[a-z]{2,})+(?:/[^\s]*)?

Matches http:// and https:// URLs.

US phone number

\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}

Matches formats like (555) 867-5309, 555-867-5309, 5558675309.

Date in YYYY-MM-DD format

\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])

Matches valid-looking dates from 2000-01-01 to 9999-12-31.

IP address (IPv4)

\b(?:\d{1,3}\.){3}\d{1,3}\b

Matches four groups of 1-3 digits separated by dots. (This allows values over 255 — true IP validation requires additional logic.)

Hex color code

#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b

Matches #fff and #ffffff style color codes.

Blank lines

^\s*$

Matches lines that are empty or contain only whitespace.

Greedy vs lazy matching

By default, quantifiers are greedy: they match as many characters as possible. In the string <b>bold</b> and <i>italic</i>, the pattern <.+> matches everything from the first < to the last > — the entire string. This is usually not what you want.

Add ? after a quantifier to make it lazy (match as few characters as possible): <.+?> now matches <b>, then </b>, then <i>, then </i> separately. That's usually the right behavior when matching HTML tags or quoted strings.

Common pitfalls

Escaping special characters. Characters like ., *, +, ?, (, ), [, ], {, }, \, ^, $, | are regex metacharacters. If you want to match a literal dot (like in a file extension), you must escape it: \.pdf not .pdf. An unescaped . matches any character.

Forgetting anchors. Without ^ and $, your pattern matches anywhere in the string. \d{5} matches "12345" anywhere in "my zip code is 12345-6789". Add anchors if you want a complete match: ^\d{5}$.

Catastrophic backtracking. Patterns like (a+)+ on a string that almost matches but ultimately doesn't can cause exponential slowdown. If your regex runs forever on certain inputs, this is usually why. Avoid nested quantifiers on similar character classes.

How to test regex in your browser

The best way to learn regex is to experiment. Toolmingo's Regex Tester lets you:

  • Write a pattern and test it against any text instantly
  • See all matches highlighted in real time
  • Test different flags (case-insensitive, global, multiline)
  • Nothing leaves your browser

Quick reference

What you want to match Pattern
Any digit \d or [0-9]
Any letter [a-zA-Z]
Any word character \w
Any whitespace \s
Any character .
Literal dot \.
Start of string ^
End of string $
0 or more *
1 or more +
Optional ?
Exactly n {n}
n to m {n,m}
Or |
Capture group (...)
Non-capture group (?:...)
Word boundary \b

FAQ

Q: Are regex patterns the same in every language? The core syntax is shared, but details differ. JavaScript, Python, Go, and Java all implement slightly different flavors. The patterns in this guide work in most common implementations. Check your language's documentation for edge cases.

Q: Should I use regex to parse HTML? Generally no, for arbitrary HTML. Regex can't handle the full complexity of nested, malformed, or recursive HTML. Use a proper HTML parser (like BeautifulSoup in Python or the DOM API in JavaScript). Regex is fine for simple, well-defined patterns in HTML snippets.

Q: How do I make a regex case-insensitive? Most implementations support a flag: /pattern/i in JavaScript, re.IGNORECASE in Python, (?i) as an inline flag. The Regex Tester tool has a case-insensitive flag you can toggle.

Q: What's the difference between * and +? * means "zero or more" — the character or group can be completely absent. + means "one or more" — there must be at least one. Use \d* if a digit section is optional; use \d+ if at least one digit is required.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools