DevPlainly
Developer Productivity

Regex Cheat Sheet: Syntax and Real Examples You Can Copy

A practical regular expression cheat sheet: characters, quantifiers, groups, lookarounds and flags, plus tested patterns for emails, dates, logs and more.

· 6 min read

Contents
  1. Characters and classes
  2. Anchors and boundaries
  3. Quantifiers
  4. Greedy vs lazy
  5. Groups and alternation
  6. Lookarounds
  7. Flags
  8. Real-world patterns
  9. Email (practical, not RFC-complete)
  10. Date in YYYY-MM-DD format
  11. Time (24-hour HH:MM)
  12. IPv4 address
  13. URL slug
  14. Strong password check
  15. Hex color
  16. Semantic version
  17. Parse a log line
  18. Find trailing whitespace (editor search)
  19. Using regex in code
  20. JavaScript
  21. Python
  22. Command line (grep and sed)
  23. Common mistakes
  24. FAQ
  25. Are regexes the same in every language?
  26. How do I test a regex?
  27. What does (?:...) mean?
  28. Further reading

Regular expressions look cryptic, but they are built from a small set of pieces. Once you know those pieces you can read most patterns, and write the ones you need for validation, search-and-replace and log parsing.

This cheat sheet covers the syntax shared by JavaScript, Python, Java, Go, PHP and most editors, followed by real-world patterns with explanations. Try any of them live in our regex tester.

Characters and classes

PatternMatches
abcThe literal text "abc"
.Any character except a newline
\dA digit (0–9)
\wA word character: letter, digit or underscore
\sWhitespace: space, tab, newline
\D, \W, \SThe opposite of \d, \w, \s
[abc]One of a, b or c
[^abc]Any character except a, b or c
[a-z]A lowercase letter
[A-Za-z0-9_-]A letter, digit, underscore or hyphen
\.A literal dot (escape special characters with \)

Characters with special meaning that must be escaped to match literally: . ^ $ * + ? ( ) [ ] { } | \ /.

Anchors and boundaries

PatternMatches
^Start of the string (or line, with the m flag)
$End of the string (or line, with the m flag)
\bA word boundary
\BNot a word boundary

\bcat\b matches "cat" in "the cat sat" but not in "concatenate".

Quantifiers

PatternMeaning
*0 or more
+1 or more
?0 or 1 (optional)
{3}Exactly 3
{2,}2 or more
{2,5}Between 2 and 5
*?, +?, ??Lazy versions: match as little as possible

Greedy vs lazy

Quantifiers are greedy by default — they match as much as possible:

Text:     <b>bold</b> and <b>more</b>
<b>.*</b>   → "<b>bold</b> and <b>more</b>"   (greedy, one big match)
<b>.*?</b>  → "<b>bold</b>", "<b>more</b>"    (lazy, two matches)

Groups and alternation

PatternMeaning
(abc)Capturing group
(?:abc)Non-capturing group (grouping without saving)
(?<year>\d{4})Named group (Python also accepts (?P<year>...))
a|ba or b
\1Back-reference to group 1

(\w+) \1 finds doubled words like "the the".

Lookarounds

Lookarounds check what comes before or after without including it in the match.

PatternMeaning
X(?=Y)X followed by Y
X(?!Y)X not followed by Y
(?<=Y)XX preceded by Y
(?<!Y)XX not preceded by Y

\d+(?= USD) matches "250" in "250 USD" without the currency. Go's standard regexp package does not support lookarounds.

Flags

FlagEffect
iCase-insensitive
gGlobal: find all matches (JavaScript)
mMultiline: ^ and $ match at each line
sDot matches newlines too
xVerbose: ignore whitespace and allow comments (Python, PCRE)

Real-world patterns

Email (practical, not RFC-complete)

^[^\s@]+@[^\s@]+\.[^\s@]+$

"Something without spaces, an @, something, a dot, something." Fully validating email addresses with a regex is not practical — the only real test is sending a confirmation email. This pattern catches typos without rejecting valid addresses.

Date in YYYY-MM-DD format

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

Checks the shape and the month/day ranges. It still allows impossible dates like 2026-02-31, so parse with a date library for real validation.

Time (24-hour HH:MM)

^([01]\d|2[0-3]):[0-5]\d$

IPv4 address

^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

Each part allows only 0–255.

URL slug

^[a-z0-9]+(?:-[a-z0-9]+)*$

Lowercase words separated by single hyphens, like regex-cheat-sheet.

Strong password check

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

At least 12 characters with a lowercase letter, an uppercase letter and a digit — each lookahead checks one rule. (Length matters more than complexity; consider just requiring a long passphrase.)

Hex color

^#(?:[0-9a-fA-F]{3}){1,2}$

Matches #fff and #1d5fd1.

Semantic version

^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$

Matches 1.4.2 and 2.0.0-beta.1.

Parse a log line

^(?<time>\S+) (?<level>INFO|WARN|ERROR) (?<service>[\w-]+) (?<message>.*)$

Applied to 2026-10-28T09:15:02Z WARN payment-service timeout after 30s, the named groups give you time, level, service and message.

[ \t]+$

With the multiline flag, this finds spaces or tabs at the end of every line — replace with nothing to clean a file.

Using regex in code

JavaScript

const re = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/;
const m = "2026-10-28".match(re);
console.log(m.groups.year); // "2026"

"a1b22c333".replace(/\d+/g, "#"); // "a#b#c#"
[..."x=1, y=22".matchAll(/(\w)=(\d+)/g)].map(m => m[2]); // ["1", "22"]

Python

import re

m = re.fullmatch(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", "2026-10-28")
print(m["year"])                         # 2026

re.sub(r"\d+", "#", "a1b22c333")         # 'a#b#c#'
re.findall(r"(\w)=(\d+)", "x=1, y=22")   # [('x', '1'), ('y', '22')]

Use raw strings (r"...") in Python so backslashes reach the regex engine unchanged. re.fullmatch requires the whole string to match; re.search finds a match anywhere.

Command line (grep and sed)

grep -E 'ERROR|WARN' app.log            # extended regex
grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' access.log | sort | uniq -c   # count IPs
sed -E 's/[[:space:]]+$//' file.txt     # strip trailing whitespace

grep and sed use POSIX regex: \d is not supported everywhere, so use [0-9] or [[:digit:]]. GNU grep's -P flag enables Perl-style syntax.

Common mistakes

  1. Forgetting anchors in validation. \d{5} matches inside "abc123456xyz". Use ^\d{5}$ (or fullmatch) to validate the whole string.
  2. Unescaped dots. example.com also matches "exampleXcom". Write example\.com.
  3. Greedy quantifiers across too much text. Use lazy quantifiers or a negated class like [^"]* instead of .*.
  4. Catastrophic backtracking. Nested quantifiers such as (a+)+ can take exponential time on some inputs, freezing a server. Keep patterns simple, and never run user-supplied regexes without a timeout.
  5. Parsing HTML or JSON with regex. Use a real parser — regex breaks on nesting and edge cases.

FAQ

Are regexes the same in every language?

The core syntax is shared, but details differ: lookbehind support, named-group syntax, Unicode handling and flags. Test patterns in the language you will use.

How do I test a regex?

Paste it into our free regex tester, which highlights matches and explains each part of the pattern, or write a small unit test with matching and non-matching examples — the test keeps working when you edit the pattern later.

What does (?:...) mean?

A non-capturing group: it groups part of a pattern (for alternation or quantifiers) without creating a numbered capture.

Further reading

Keep reading