A regex tester online lets you write a regular expression, paste sample text, and see matches highlighted in real time — no IDE, no terminal, no trial-and-error commit cycle. Debugging a regex that almost works is one of the most frustrating experiences in development; an interactive tester turns it into a readable, visual process.

Test your regex now →

Why Use an Online Regex Tester?

Regular expressions are notoriously hard to read and debug from memory. An online tester gives you:

  • Instant feedback — see which parts of your text match as you type
  • Flag control — toggle g, i, m, s flags without rewriting code
  • Capture group inspection — see exactly what each () group captured
  • Safe iteration — experiment without touching production code

Regex Flags

Flags change how a pattern matches. Understanding them prevents the most common regex bugs:

FlagMeaning
gGlobal — find all matches, not just the first
iCase-insensitive — [A-Z] also matches [a-z]
mMultiline — ^ and $ match start/end of each line
sDot-all — . matches newline characters too
uUnicode — enable full Unicode matching
dIndices — include start/end indices for match groups

The most common mistake: forgetting the g flag when you expect multiple matches.

Core Regex Syntax

Character Classes

\d        — any digit [0-9]
\D        — any non-digit
\w        — word character [a-zA-Z0-9_]
\W        — non-word character
\s        — whitespace (space, tab, newline)
\S        — non-whitespace
.         — any character except newline (add s flag for newline)
[abc]     — character class: a, b, or c
[^abc]    — negated class: anything except a, b, c
[a-z]     — range: lowercase a through z
[a-zA-Z] — range: any letter

Quantifiers

*         — 0 or more (greedy)
+         — 1 or more (greedy)
?         — 0 or 1 (optional)
{3}       — exactly 3
{3,}      — 3 or more
{3,6}     — between 3 and 6 (inclusive)
*?        — 0 or more (lazy/non-greedy)
+?        — 1 or more (lazy/non-greedy)

Greedy vs lazy: <.+> on <a>foo</a> matches the whole string. <.+?> matches <a> and </a> separately.

Anchors

^         — start of string (or line with m flag)
$         — end of string (or line with m flag)
\b        — word boundary
\B        — non-word boundary

Groups and Capturing

(abc)     — capturing group: captures "abc" as group 1
(?:abc)   — non-capturing group: groups but doesn't capture
(?<name>abc) — named capturing group: access as groups.name
(a|b)     — alternation: matches "a" or "b"

Lookahead and Lookbehind

(?=abc)   — positive lookahead: followed by "abc"
(?!abc)   — negative lookahead: NOT followed by "abc"
(?<=abc)  — positive lookbehind: preceded by "abc"
(?<!abc)  — negative lookbehind: NOT preceded by "abc"

Lookarounds match a position, not characters — they don’t consume input.

Practical Regex Patterns

Email Address Validation

^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$

This covers the common case. A fully RFC 5321-compliant email regex is impractical — for production, use a library or a simple format check plus confirmation email.

URL Matching

https?:\/\/[^\s/$.?#].[^\s]*

Matches http:// and https:// URLs. For stricter validation (protocol, domain, path, query, fragment):

^(https?:\/\/)([a-zA-Z0-9\-]+\.)+[a-zA-Z]{2,}(\/[^\s]*)?$

IPv4 Address

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

Validates each octet is 0–255.

Semantic Version (semver)

^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z\-][0-9a-zA-Z\-]*))*))?(?:\+([0-9a-zA-Z\-]+(?:\.[0-9a-zA-Z\-]+)*))?$

Full semver compliance including pre-release and build metadata.

ISO 8601 Date

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

Matches YYYY-MM-DD format with basic range validation.

Extract Numbers from Text

-?\d+(?:\.\d+)?

Matches integers and decimals, optionally negative. Useful for parsing log output or config files.

Hex Color Code

#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\b

Matches both 3-digit (#fff) and 6-digit (#ffffff) hex colors.

Log Line Parsing

^(?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})\s+(?<level>ERROR|WARN|INFO|DEBUG)\s+(?<message>.+)$

With named capture groups, you get structured data from unstructured log lines.

Regex in Code

JavaScript

// Basic match
const email = 'user@example.com';
const pattern = /^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$/;
console.log(pattern.test(email)); // true

// Extract all matches (g flag required)
const text = 'Prices: $12.50, $199, $0.99';
const prices = text.match(/\$\d+(?:\.\d{2})?/g);
// ['$12.50', '$199', '$0.99']

// Named capture groups
const log = '2026-04-07T14:23:01 ERROR connection refused';
const logPattern = /^(?<ts>\S+)\s+(?<level>\w+)\s+(?<msg>.+)$/;
const { ts, level, msg } = log.match(logPattern).groups;

// Replace with back-reference
const camelToSnake = str => str.replace(/([A-Z])/g, '_$1').toLowerCase();
camelToSnake('camelCaseString'); // 'camel_case_string'

Python

import re

# Search and extract
text = "Order #12345 placed on 2026-04-07"
m = re.search(r'#(\d+)', text)
if m:
    print(m.group(1))  # '12345'

# Find all matches
emails = re.findall(r'[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}', text)

# Named groups
pattern = re.compile(
    r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
)
m = pattern.search(text)
print(m.group('year'), m.group('month'), m.group('day'))

# Substitution
result = re.sub(r'\b(\w+)\b', lambda m: m.group().upper(), 'hello world')
# 'HELLO WORLD'

Go

import "regexp"

// Compile once, reuse
emailRe := regexp.MustCompile(`^[\w.%+\-]+@[\w\-]+\.[a-zA-Z]{2,}$`)
fmt.Println(emailRe.MatchString("user@example.com")) // true

// Find all
re := regexp.MustCompile(`\$\d+(?:\.\d{2})?`)
matches := re.FindAllString("Prices: $12.50 and $199", -1)
// ["$12.50", "$199"]

// Named submatches
re = regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})`)
match := re.FindStringSubmatch("2026-04")
names := re.SubexpNames()
// map names to matches by iterating names

Common Regex Mistakes

Forgetting to escape special characters., *, +, ?, (, ), [, ], {, }, ^, $, |, \ are metacharacters. To match a literal dot, write \..

Using greedy quantifiers when lazy is needed<.+> matches everything from the first < to the last >. Use <.+?> to match individual tags.

Missing the g flag in JavaScriptstring.match(/pattern/) without g returns only the first match. Add g for all matches.

Using ^ and $ without the m flag in multiline text — without m, ^ matches only the start of the entire string, not each line.

Catastrophic backtracking — patterns like (a+)+ on long non-matching strings can cause exponential time complexity. Avoid nested quantifiers on overlapping character classes.

Over-engineering email validation — the canonical RFC-compliant email regex is 6,000+ characters and still doesn’t prevent all invalid emails. Use format check + confirmation instead.

Test Your Regex Interactively

ZeroTool’s Regex Tester gives you a split-pane editor where you write your pattern on the left and paste sample text on the right. Matches highlight in real time, capture groups are shown below, and you can toggle flags with one click.

No installation. No rate limits. Runs entirely in your browser.

Open the Regex Tester →