Skip to content
Deftkit

Regex Tester — Test Regular Expressions Online

Test JavaScript regular expressions against any text. Live match highlighting, capture groups, all flags. Free, fast, runs entirely in your browser.

Live regex testing — edit the pattern, flags, or text and the matches update instantly. Uses your browser's native JavaScript regex engine.

//gi

2 matches

Email me at alice@example.com or bob@toolboxes.dev — also try carol@old-mail.org for backup.

Match details

#1 @ 12alice@example.com
$1: "alice"
$2: "example.com"
#2 @ 33bob@toolboxes.dev
$1: "bob"
$2: "toolboxes.dev"

What is a regular expression?

A regular expression — regex for short — is a small pattern language for matching text. Instead of asking "does this string contain the literal word foo", regex lets you ask things like "does this string contain a sequence of digits between 3 and 6 long" or "extract the username and domain from any email-shaped substring" or "find every line that starts with a hash followed by whitespace." Most programming languages, command line tools, and text editors include a regex engine, and most use a syntax close enough to JavaScript's that this tool will help you debug them.

This tester runs against the browser's native JavaScript regex engine — the same engine your code uses when you write const re = /foo/g. The pattern you type here will behave identically when pasted into Node.js, Deno, Bun, or any modern browser. It will be close to but not identical to PCRE (Perl), Python re, Ruby, Go, or grep — the differences are usually around lookbehind support, named-group syntax, and Unicode escapes.

How to use this regex tester

  1. Type your pattern into the Patternfield. Don't include the slashes — the tool adds them for you.
  2. Toggle the flags you need: g for global (find all matches), i for case-insensitive, m for multiline, s for dotAll, u for full Unicode, y for sticky.
  3. Paste or type the text you want to match against into the Test string textarea.
  4. Matches highlight in yellow as you type. The match count and a per-match breakdown (with capture groups) appear below.
  5. Click Copy regex to put the literal /pattern/flags on your clipboard for pasting into code.

Common patterns to start from

Email (rough):              \w+@\w+\.\w+
URL (rough):                https?://[\w./?=&-]+
Numbers only:               \d+
Alphanumeric word:          \w+
Whitespace:                 \s+
Start of line:              ^
End of line:                $
Hex color:                  #[0-9a-fA-F]{3,6}
US phone (rough):           \(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}
ISO date (YYYY-MM-DD):      \d{4}-\d{2}-\d{2}
IPv4 octet (rough):         \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
Capture before/after =:     ^(\w+)=(.*)$
Named groups:               (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})

These are starting points, not production-ready validators. Email addresses and URLs are notoriously hard to validate exactly with regex (the official email spec runs to thousands of valid forms), and the "rough" patterns above will accept some invalid inputs and reject some valid ones. For validation, use a dedicated library; regex is for finding and extracting, not for proving well-formedness.

Flags explained

  • g — global. Find all matches in the string, not just the first. Without g, calling .match() returns only the first match. With it, you get an iterable of all matches. This tester uses matchAll wheng is set.
  • i — ignoreCase. Treats letters as case-insensitive. /foo/i matches Foo, FOO, fOO, etc.
  • m — multiline. Makes ^ and $ match at line boundaries inside the string, not just at the very start and end. Useful for per-line processing.
  • s — dotAll. Makes the . metacharacter match newline characters too. Without it, dot excludes line terminators.
  • u — unicode. Enables full Unicode support including code points above U+FFFF (emoji, rare CJK), and treats escape sequences like \u{1F600} as single code points. Always include this when working with non-ASCII text.
  • y — sticky. Match must start at exactly regex.lastIndex. Niche; useful for tokenizers and parsers.

Capture groups — extracting parts of a match

Parentheses in a pattern create capture groups. When the regex matches, each group's contents are available separately in addition to the full match. The tester shows them as $1, $2, etc. below each match.

For example, the pattern (\\w+)@(\\w+\\.\\w+) against alice@example.com matches the whole string and exposes two groups: $1 = alice and $2 = example.com.

Named groups use the syntax (?<name>...) and let you refer to a group by name in your code via match.groups.name. The tester displays them with their name in angle brackets next to the positional index.

Non-capturing groups use the syntax (?:...)— they group for alternation or quantification but don't produce a captured value. Use these when you need parentheses for the regex syntax but don't need to extract the contents.

Common regex pitfalls

  • Greedy vs lazy quantifiers. .* is greedy — it matches as much as possible, then backtracks. .*? is lazy — it matches as little as possible. The difference matters when there are multiple ways to satisfy a pattern.
  • Anchors are pickier than you think. ^ and $ match the start and end of the entire input by default. Add the m flag if you want them to match per-line.
  • Escaping the slash inside a literal regex. When writing /.../ in JavaScript source, a literal slash inside the pattern must be escaped as \\/. The tester handles this for you because the pattern field is plain text — but remember to add the escape when you copy the pattern back to code.
  • Unicode trip-ups. Without the u flag, . matches code units, not code points. Emoji and rare CJK characters can mismatch in subtle ways. When in doubt, add u.
  • Catastrophic backtracking. Patterns like (a+)+b on input aaaaaaaaaaaaaaa! can take exponential time as the engine tries every possible decomposition. If your tester locks up, this is probably why — simplify the pattern or add explicit anchors.

Privacy and security

The pattern, the test string, and the match results all stay in your browser. Regex evaluation happens via the browser's native engine, not on a server. There is no upload, no log, no copy stored anywhere. You can safely test patterns against production strings, customer data, or anything else sensitive — none of it leaves your machine.

Frequently asked questions

Is JavaScript regex the same as PCRE / Python / Ruby regex?

Mostly the same for the common cases (character classes, quantifiers, alternation, capture groups, anchors). Differences: JavaScript only added lookbehind assertions in ES2018 (older engines reject them), named groups use (?<name>...) in JS but (?P<name>...) in Python, Unicode property escapes like \\p{Letter} require the uflag in JS, and possessive quantifiers and atomic groups (PCRE features) are not available in JS. For most patterns the differences don't matter; for anything fancy, test the pattern in your target language too.

Why does my pattern fail when I copy it from the tester to code?

Two common reasons: (a) when you write the regex as a JavaScript literal /pattern/, you don't need to escape the backslashes any further; but when you write it as a string for the RegExp constructor, you must double-escape (new RegExp("\\\\d+")), because the string parser eats one layer of backslashes first; (b) the tester always shows the "normal" form, so a pattern containing a literal slash will work in the tester but needs \\/ when pasted into a literal regex.

How can I see what each part of the regex is doing?

This tester shows match positions and capture groups but not a per-token explanation. For a syntax breakdown, paste your regex into regex101.com or similar — they have explanation panes that label every metacharacter and quantifier. We may add an explainer in a future version.

Why does my global match return zero-length empty matches?

Patterns that can match an empty string (like a* or \\b) will return zero-width matches at every position the engine tries. Most engines handle this by advancing the cursor by one position after each empty match to avoid an infinite loop. The tester counts these but doesn't highlight them in the preview because there's nothing to draw a box around.

Is my data sent anywhere?

No. Pattern, test string, and match results all stay in your browser. Native JavaScript regex engine, no network requests, no log.