Bookmark this page. Use Ctrl+F (or Cmd+F on Mac) to find what you need. This cheat sheet covers regex patterns that work in most languages (JavaScript, Python, Java, Rust, Go). Test your patterns at regex101.com.

Last updated: March 2026

Basic Patterns

PatternMatchesExample
abcLiteral text “abc”abc matches “abcdef”
.Any character (except newline)a.c matches “abc”, “a1c”
^Start of string/line^Hello matches “Hello world”
$End of string/lineworld$ matches “Hello world
\Escape special character\. matches a literal dot

Character Classes

PatternMatches
[abc]a, b, or c
[a-z]Any lowercase letter
[A-Z]Any uppercase letter
[0-9]Any digit
[a-zA-Z0-9]Any letter or digit
[^abc]NOT a, b, or c
[^0-9]NOT a digit

Shorthand Classes

PatternMatchesEquivalent
\dAny digit[0-9]
\DNOT a digit[^0-9]
\wWord character[a-zA-Z0-9_]
\WNOT a word character[^a-zA-Z0-9_]
\sWhitespace[ \t\n\r\f]
\SNOT whitespace[^ \t\n\r\f]
\bWord boundaryBetween \w and \W
\BNOT a word boundary

Quantifiers

PatternMeaningExample
a*0 or morebo* matches “b”, “bo”, “boooo”
a+1 or morebo+ matches “bo”, “boooo” (not “b”)
a?0 or 1 (optional)colou?r matches “color”, “colour”
a{3}Exactly 3\d{3} matches “123
a{2,4}2 to 4\d{2,4} matches “12”, “123”, “1234
a{2,}2 or more\d{2,} matches “12”, “12345

Greedy vs Lazy

Greedy (default):  .*   matches as MUCH as possible
Lazy (add ?):      .*?  matches as LITTLE as possible

Text:    <div>hello</div><div>world</div>
Greedy:  <.*>    matches "<div>hello</div><div>world</div>"
Lazy:    <.*?>   matches "<div>"

Groups and Capturing

PatternDescription
(abc)Capture group — matches “abc” and captures it
(?:abc)Non-capturing group — matches but does not capture
(a|b)Alternation — matches “a” OR “b”
\1Back-reference — matches same text as group 1
Pattern:  (\w+)\s+\1
Text:     "the the quick brown fox"
Matches:  "the the" (repeated word)

Named Groups

Pattern:  (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
Text:     "2026-03-15"
Groups:   year=2026, month=03, day=15

Lookahead and Lookbehind

PatternNameDescription
(?=abc)Positive lookaheadFollowed by “abc”
(?!abc)Negative lookaheadNOT followed by “abc”
(?<=abc)Positive lookbehindPreceded by “abc”
(?<!abc)Negative lookbehindNOT preceded by “abc”

Lookaround does NOT consume characters — it only checks.

Note: Lookbehind support varies by engine. JavaScript and Python support it. Rust’s regex crate does NOT support lookbehind. Always check your engine’s docs.

// Positive lookahead: digits followed by "px"
\d+(?=px)     matches "12" in "12px" but not in "12em"

// Negative lookahead: digits NOT followed by "px"
\d+(?!px)     matches "12" in "12em" but not in "12px"

// Positive lookbehind: digits preceded by "$"
(?<=\$)\d+    matches "100" in "$100" but not in "€100"

Flags

FlagNameDescription
gGlobalFind all matches (not just first)
iCase-insensitivea matches “A”
mMultiline^ and $ match line start/end
sDotall. matches newlines too
uUnicodeFull Unicode support
/hello/gi        // global + case-insensitive

Common Patterns

Email (simplified)

[\w.+-]+@[\w-]+\.[\w.]+

Matches: alex@example.com, user.name+tag@sub.domain.com

URL

https?://[\w\-._~:/?#\[\]@!$&'()*+,;=%]+

Phone Number (international)

\+?\d{1,3}[-.\s]?\(?\d{1,4}\)?[-.\s]?\d{1,4}[-.\s]?\d{1,9}

IP Address (IPv4)

\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b

Date (YYYY-MM-DD)

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

Password Strength (min 8 chars, 1 upper, 1 lower, 1 digit)

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$

HTML Tag

<(\w+)[^>]*>.*?</\1>

Whitespace Cleanup

\s+          matches all whitespace sequences
^\s+|\s+$    leading or trailing whitespace
\s{2,}       multiple spaces (replace with single)

Language-Specific Syntax

JavaScript

const regex = /\d+/g;
const matches = "abc 123 def 456".match(regex);   // ["123", "456"]
"hello".replace(/l/g, "r");                         // "herro"
/\d+/.test("abc123");                               // true

Python

import re
matches = re.findall(r"\d+", "abc 123 def 456")    # ["123", "456"]
re.sub(r"l", "r", "hello")                          # "herro"
bool(re.search(r"\d+", "abc123"))                    # True
match = re.search(r"(?P<year>\d{4})", "2026-03-15")
match.group("year")                                  # "2026"

Rust

use regex::Regex;
let re = Regex::new(r"\d+").unwrap();
let matches: Vec<&str> = re.find_iter("abc 123 def 456")
    .map(|m| m.as_str()).collect();                  // ["123", "456"]
re.is_match("abc123");                               // true

Common Mistakes

  1. Not escaping special characters. matches ANY character, not a literal dot. Use \. for a literal dot. Same for *, +, ?, (, ), [, ], {, }, ^, $, |, \.

  2. Greedy matching by default.* grabs as much as possible. Use .*? for the shortest match. This matters when matching HTML tags, quoted strings, or any paired delimiters.

  3. Validating email with regex — Simple patterns reject valid emails. Complex patterns become unreadable. For production email validation, check for @ and a dot, then send a verification email.