DevToolBoxGRATIS
Blog

Regex Cheat Sheet: Riferimento completo per le espressioni regolari

12 min di letturadi DevToolBox

Regular expressions (regex) are one of the most powerful tools in a developer's arsenal. Whether you are validating user input, parsing log files, or performing complex search-and-replace operations, regex gives you unmatched precision. This complete regex cheat sheet covers every major concept: anchors, character classes, quantifiers, groups, lookarounds, flags, and cross-language usage. Bookmark this page and refer to it whenever you need a quick refresher.

Try every pattern live in our Regex Tester ->

Basic Syntax: Anchors & Character Classes

Anchors and character classes form the foundation of every regex pattern. Anchors specify where in the string a match should occur. Character classes define what characters to match.

Anchors

Anchors do not match characters themselves; they match positions within the string.

PatternDescriptionExample
^Start of string (or line with m flag)^Hello matches "Hello World"
$End of string (or line with m flag)world$ matches "Hello world"
\bWord boundary\bcat\b matches "cat" but not "catch"
\BNon-word boundary\Bcat\B matches "concatenate"
\AAbsolute start of string (Python, Ruby)\AHello
\ZAbsolute end of string (Python, Ruby)bye\Z

Character Classes

Character classes let you match a set of characters in a single position.

PatternDescriptionEquivalent
[abc]Match a, b, or c--
[^abc]Match anything except a, b, c--
[a-z]Match any lowercase letter--
[A-Z]Match any uppercase letter--
[0-9]Match any digit\d
.Match any character (except newline by default)--
\dDigit[0-9]
\DNon-digit[^0-9]
\wWord character[a-zA-Z0-9_]
\WNon-word character[^a-zA-Z0-9_]
\sWhitespace (space, tab, newline)[ \t\n\r\f\v]
\SNon-whitespace[^ \t\n\r\f\v]

Special Characters (Metacharacters)

These characters have special meaning in regex. To match them literally, escape them with a backslash.

Special characters that need escaping:
.  ^  $  *  +  ?  {  }  [  ]  \  |  (  )

To match a literal dot:   \.
To match a literal star:  \*
To match a literal pipe:  \|
To match a backslash:     \\

Quantifiers: How Many Times to Match

Quantifiers control how many times a preceding element must appear for a match. By default, quantifiers are greedy -- they match as much as possible. Appending ? makes them lazy (match as little as possible).

GreedyLazyDescription
**?0 or more times
++?1 or more times
???0 or 1 time (optional)
{n}{n}?Exactly n times
{n,}{n,}?n or more times
{n,m}{n,m}?Between n and m times

Greedy vs. Lazy Quantifiers

Consider the string <b>bold</b> and <i>italic</i>. A greedy pattern <.*> matches the entire string from the first < to the last >. The lazy version <.*?> matches only <b>, stopping at the first >.

// Input string:
const str = '<b>bold</b> and <i>italic</i>';

// Greedy: matches from first < to LAST >
str.match(/<.*>/);
// Result: '<b>bold</b> and <i>italic</i>'

// Lazy: matches from first < to FIRST >
str.match(/<.*?>/);
// Result: '<b>'

Groups & Capturing

Groups let you treat multiple characters as a single unit, apply quantifiers to sub-expressions, and extract matched portions.

Capturing Groups

Wrap a sub-expression in parentheses (...) to capture its match. You can reference captured groups with backreferences like \1, \2, etc.

// Capturing group example
const dateRegex = /^(\d{4})-(\d{2})-(\d{2})$/;
const match = '2026-02-10'.match(dateRegex);
// match[0] = '2026-02-10'  (full match)
// match[1] = '2026'        (year)
// match[2] = '02'          (month)
// match[3] = '10'          (day)

// Backreference: match repeated words
const repeated = /\b(\w+)\s+\1\b/;
repeated.test('the the');  // true
repeated.test('the cat');  // false

Named Groups

Named groups improve readability. In JavaScript and Python, use (?<name>...) syntax.

// Named groups in JavaScript
const dateRegex = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/;
const match = '2026-02-10'.match(dateRegex);
// match.groups.year  = '2026'
// match.groups.month = '02'
// match.groups.day   = '10'
# Named groups in Python
import re
pattern = r'^(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})$'
m = re.match(pattern, '2026-02-10')
# m.group('year')  = '2026'
# m.group('month') = '02'
# m.group('day')   = '10'

Non-Capturing Groups

Use (?:...) when you need grouping but do not need to capture the match. This is more efficient for complex patterns.

// Non-capturing group
const regex = /(?:https?|ftp):\/\/[^\s]+/;
// Groups the protocol options without capturing them
// Only the full URL is in match[0]

Alternation (OR)

Use the pipe | inside a group to match one of several alternatives.

// Alternation examples
/cat|dog/           // Match "cat" or "dog"
/(red|blue) car/    // Match "red car" or "blue car"
/^(GET|POST|PUT|DELETE)\s/  // Match HTTP methods

Lookahead & Lookbehind (Zero-Width Assertions)

Lookarounds assert that a certain pattern exists (or does not exist) ahead of or behind the current position, without consuming characters. This makes them incredibly powerful for complex matching conditions.

SyntaxTypeDescription
(?=...)Positive lookaheadWhat follows must match
(?!...)Negative lookaheadWhat follows must NOT match
(?<=...)Positive lookbehindWhat precedes must match
(?<!...)Negative lookbehindWhat precedes must NOT match

Positive Lookahead (?=...)

Matches a position that is followed by the specified pattern.

// Match a number followed by "px"
/\d+(?=px)/
// "20px 30em 40px" → matches "20" and "40" (not "30")

// Password: must contain at least one digit
/^(?=.*\d).{8,}$/

Negative Lookahead (?!...)

Matches a position that is not followed by the specified pattern.

// Match "cat" NOT followed by "fish"
/cat(?!fish)/
// "catfish catdog" → matches "cat" in "catdog" only

// Match numbers NOT followed by a unit
/\d+(?!\s*(px|em|rem|%))/

Positive Lookbehind (?<=...)

Matches a position that is preceded by the specified pattern.

// Match a number preceded by "$"
/(?<=\$)\d+(\.\d{2})?/
// "$49.99 and €29.99" → matches "49.99" only

// Extract value after "price:"
/(?<=price:\s*)\d+/

Negative Lookbehind (?<!...)

Matches a position that is not preceded by the specified pattern.

// Match "cat" NOT preceded by "wild"
/(?<!wild)cat/
// "wildcat housecat" → matches "cat" in "housecat" only

// Match digits not preceded by a minus sign
/(?<!-)\b\d+\b/

Note: Lookbehinds have limited support in some regex engines. JavaScript (ES2018+) supports them, but older engines may not. Python and Go support lookbehinds with fixed-length patterns.

Regex Flags (Modifiers)

Flags modify how the regex engine interprets the pattern. They are placed after the closing delimiter (e.g., /pattern/gi in JavaScript) or passed as arguments in functions.

FlagNameDescriptionExample
gGlobalFind all matches, not just the first/cat/g finds all "cat" occurrences
iCase-insensitiveMatch upper and lowercase interchangeably/hello/i matches "Hello", "HELLO"
mMultiline^ and $ match line starts/ends/^start/m matches at each line start
sDotall (Single-line). matches newline characters too/a.b/s matches "a\nb"
uUnicodeEnable full Unicode matching/\u{1F600}/u matches emoji
yStickyMatch only at lastIndex positionUsed for tokenizing / lexing
// Combining flags
const regex = /^hello world$/gim;

// In Python, flags are constants:
import re
pattern = re.compile(r'^hello world$', re.IGNORECASE | re.MULTILINE)

// In Go, use inline flags:
// (?i) for case-insensitive, (?m) for multiline, (?s) for dotall
regexp.MustCompile("(?im)^hello world$")

Common Patterns Quick Reference

Here are the most frequently needed regex patterns. Test any of them in our regex tester tool.

Use CasePattern
Email^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
URL (HTTP/S)^https?:\/\/[^\s]+$
IPv4 Address^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$
Date (YYYY-MM-DD)^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
Time (HH:MM:SS)^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$
Hex Color^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$
Strong Password^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$
Phone (E.164)^\+[1-9]\d{1,14}$
UUID^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
Semantic Version^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[\w.]+)?(\+[\w.]+)?$
HTML Tag<([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>(.*?)<\/\1>
Trim Whitespace^\s+|\s+$

Test all these patterns live with our Regex Tester ->

Regex in Different Programming Languages

While regex syntax is largely universal, each language has its own API for creating, testing, and applying patterns. Here are the key differences.

JavaScript

// Creating regex in JavaScript
const regex1 = /^\d+$/;             // Literal syntax
const regex2 = new RegExp('^\\d+$'); // Constructor (needs double-escape)

// Testing
regex1.test('12345');                // true

// Matching
'hello world'.match(/\w+/g);        // ['hello', 'world']

// Replacing
'2026-02-10'.replace(
  /^(\d{4})-(\d{2})-(\d{2})$/,
  '$2/$3/$1'
);  // '02/10/2026'

// matchAll (ES2020) - get all matches with groups
const text = 'Price: $10, Tax: $2';
for (const m of text.matchAll(/\$(\d+)/g)) {
  console.log(m[0], m[1]);
  // '$10' '10', then '$2' '2'
}

// Named groups (ES2018+)
const { groups } = '2026-02-10'.match(
  /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
);
console.log(groups.year);  // '2026'

Python

import re

# Compile for reuse (recommended)
pattern = re.compile(r'^\d+$')

# Test if the entire string matches
pattern.match('12345')      # Match object (truthy)
pattern.match('abc')        # None (falsy)

# Search anywhere in the string
re.search(r'\d+', 'abc 123 def')  # Finds '123'

# Find all matches
re.findall(r'\w+', 'hello world')  # ['hello', 'world']

# Replace
re.sub(
    r'^(\d{4})-(\d{2})-(\d{2})$',
    r'\2/\3/\1',
    '2026-02-10'
)  # '02/10/2026'

# Named groups
m = re.match(
    r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})',
    '2026-02-10'
)
m.group('year')   # '2026'
m.group('month')  # '02'

# Flags
re.findall(r'^start', text, re.MULTILINE | re.IGNORECASE)

# Split by pattern
re.split(r'[,;\s]+', 'a, b; c  d')  # ['a', 'b', 'c', 'd']

Go (Golang)

package main

import (
    "fmt"
    "regexp"
)

func main() {
    // Compile (panics on invalid pattern)
    re := regexp.MustCompile(`^\d+$`)

    // Test
    fmt.Println(re.MatchString("12345"))  // true
    fmt.Println(re.MatchString("abc"))    // false

    // Find first match
    re2 := regexp.MustCompile(`\d+`)
    fmt.Println(re2.FindString("abc 123 def"))  // "123"

    // Find all matches
    fmt.Println(re2.FindAllString("10 cats and 20 dogs", -1))
    // ["10", "20"]

    // Replace
    re3 := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
    result := re3.ReplaceAllString("2026-02-10", "$2/$3/$1")
    fmt.Println(result)  // "02/10/2026"

    // Named groups
    re4 := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
    match := re4.FindStringSubmatch("2026-02-10")
    for i, name := range re4.SubexpNames() {
        if name != "" {
            fmt.Printf("%s: %s\n", name, match[i])
        }
    }
    // year: 2026, month: 02, day: 10

    // Inline flags: (?i) case-insensitive, (?m) multiline, (?s) dotall
    re5 := regexp.MustCompile(`(?i)hello`)
    fmt.Println(re5.MatchString("HELLO"))  // true
}

Go uses the RE2 engine, which does not support lookaheads, lookbehinds, or backreferences. This is a deliberate design decision for guaranteed linear-time matching.

Performance Tips & Best Practices

Be specific: Use [a-zA-Z] instead of . when you know what characters to expect. Specific patterns are faster and less error-prone.

Avoid catastrophic backtracking: Nested quantifiers like (a+)+ can cause exponential time complexity. Use atomic groups or possessive quantifiers where available.

// BAD: Catastrophic backtracking risk
const bad = /^(a+)+$/;
bad.test('aaaaaaaaaaaaaaaaaaaaa!');  // Extremely slow!

// GOOD: Flatten nested quantifiers
const good = /^a+$/;
good.test('aaaaaaaaaaaaaaaaaaaaa!'); // Instant: false

Use non-capturing groups: When you do not need to extract matched text, use (?:...) instead of (...) to improve performance.

Compile once, use many: In languages like Python and Go, compile your regex once and reuse the compiled object for better performance.

# Python: compile once, reuse many times
import re
email_re = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')

# Fast: uses pre-compiled pattern
for addr in addresses:
    if email_re.match(addr):
        print(f"Valid: {addr}")

Test incrementally: Build complex patterns step by step. Test each part individually before combining them.

Try every pattern live in our Regex Tester ->

Frequently Asked Questions

What is a regex cheat sheet and why do I need one?

A regex cheat sheet is a quick-reference guide that lists regex syntax, metacharacters, quantifiers, flags, and common patterns in one place. Even experienced developers cannot memorize every regex construct. Having a cheat sheet saves time and reduces errors when writing regular expressions for tasks like input validation, text extraction, and log parsing.

What is the difference between .* and .*? in regex?

The pattern .* is a greedy quantifier that matches as many characters as possible (the longest match), while .*? is a lazy (or non-greedy) quantifier that matches as few characters as possible (the shortest match). For example, given the string "<b>hello</b>", the pattern <.*> matches the entire string, but <.*?> matches only "<b>". Use lazy quantifiers when you want to stop at the first occurrence of a delimiter.

Do all programming languages support the same regex syntax?

Most languages support PCRE (Perl Compatible Regular Expressions) or a close variant, so core features like character classes, quantifiers, and groups work everywhere. However, advanced features differ: JavaScript added lookbehinds in ES2018, Go (RE2 engine) does not support lookbehinds or backreferences at all, and Python supports all major features through the re module. Always check your language documentation for supported features.

How can I test and debug regex patterns?

The best way to test regex patterns is to use an interactive regex tester that shows matches in real time. Our Regex Tester tool at DevToolBox lets you enter a pattern and test string, see matches highlighted, and view captured groups. Build your pattern step by step, testing each part individually. This approach catches mistakes early and helps you understand how the engine processes your pattern.

What is catastrophic backtracking and how do I avoid it?

Catastrophic backtracking occurs when a regex engine takes exponentially long to determine that a string does not match a pattern. It typically happens with nested quantifiers like (a+)+ or overlapping alternatives. To avoid it: be as specific as possible with character classes, avoid nested repetition, use atomic groups or possessive quantifiers (if your engine supports them), and test your patterns against long non-matching strings to catch performance issues.

𝕏 Twitterin LinkedIn
È stato utile?

Resta aggiornato

Ricevi consigli dev e nuovi strumenti ogni settimana.

Niente spam. Cancella quando vuoi.

Prova questi strumenti correlati

.*Regex TesterR✓Regex CheckerR≈Regex MatcherR+Regex Generator

Articoli correlati

20 Pattern Regex che ogni sviluppatore deve conoscere: Esempi pronti da copiare

Collezione di 20 pattern regex testati per email, URL, telefono, password, indirizzo IP e altro.

Regex per email, telefono, URL e IP: Pattern pronti da copiare

Pattern regex pronti da copiare per validare email, numeri di telefono, URL e indirizzi IP.

Regex Tester Online: Test, Debug & Validate Regular Expressions (2026 Guide)

Use our free online regex tester to test regular expressions in real time. Covers JavaScript, Python, and Go regex syntax, 10 must-know patterns, common mistakes, performance tips, and when to skip regex.