Webtools

Regex Tester

Test JavaScript regex with live highlighting

/ /

Common flags: g global, i case-insensitive, m multiline, s dotAll, u unicode.

Match details

What is a regex tester?

A regular expression is a compact, declarative way to describe a pattern in text — find every email address in a document, validate that a phone number matches the right format, replace every occurrence of a date in DD/MM/YYYY form with YYYY-MM-DD, or split a CSV row at the right commas. Regular expressions are supported by every major programming language and most text editors, but writing them is error-prone: a single misplaced quantifier can match too much, too little, or fail to compile entirely. A regex tester shows you exactly what your pattern matches in a given test string, so you can iterate quickly without bouncing back and forth to the language's REPL.

This tester uses the JavaScript / ECMAScript regex engine — the same one running inside your browser — and supports the full ECMAScript 2025 feature set: capture groups (numbered and named), lookaround (lookbehind included), Unicode property escapes (\p{Letter}), and all six standard flags. As you type, every match in the test string is highlighted, and capture groups are listed below for each match with their captured text and the index where each one starts. Pattern errors are reported inline so you can fix them as you go. The pattern, flags, and test string are all evaluated in your browser; nothing is sent to a server.

Most regex syntax is portable: a pattern that works in JavaScript will usually work in PCRE (PHP, Python, Ruby), .NET, Go, and Rust with at most cosmetic changes. The differences are in the corners — possessive quantifiers (*+, ++) exist in PCRE but not JavaScript; conditionals ((?(1)yes|no)) are PCRE-only; some Unicode escapes have slightly different names. The portability sections below highlight the differences worth knowing.

Regex syntax in detail

The regex grammar is small but expressive. Below is a tour of each construct with a working example you can paste into the tester to see how it behaves.

Anchors

^start end$ \bword\b

^ matches the start of the input (or the start of any line if the m flag is set), $ matches the end. \b is a word boundary — the gap between a word character and a non-word character. Anchors are zero-width: they assert a position but do not consume any characters.

Character classes

\d \w \s [a-z] [^0-9]

\d matches a digit (0–9 by default; any Unicode digit with the u flag), \w a word character ([A-Za-z0-9_]), \s any whitespace. Custom classes use square brackets — [a-z] for a range, [^0-9] to negate the class. . matches any character except newline (any character including newline with the s flag).

Quantifiers

a* a+ a? a{3} a{2,5}

* matches zero or more, + one or more, ? zero or one. {n} exactly n, {n,m} between n and m, {n,} n or more. All quantifiers are greedy by default — they match as much as possible while still allowing the rest of the pattern to match. Suffix any of them with ? to make them lazy: .*? matches as little as possible.

Alternation

cat|dog|fish

| matches either side. The engine tries the alternatives left-to-right and takes the first one that succeeds — so int|integer against "integer" will match the leading int and stop. Reorder to put longer alternatives first when this matters: integer|int.

Capture groups

(\d{4})-(\d{2})-(\d{2})

Parentheses create a numbered capture group, accessible as $1, $2 in replacements. Use (?:...) for a non-capturing group when you only need the grouping. Named groups use (?<year>\d{4}) and back-reference as \k<year>. Numbered backreferences use \1, \2 inside the pattern.

Lookaround

foo(?=bar) foo(?!bar)

Lookahead and lookbehind are zero-width assertions that match a position based on what follows or precedes, without consuming characters. foo(?=bar) matches foo only when followed by bar; foo(?!bar) only when not followed by bar; (?<=foo)bar matches bar only when preceded by foo. JavaScript supports lookbehind since ES2018; some older PCRE versions only allow fixed-length lookbehind.

Unicode property escapes

\p{Letter} \p{Script=Greek}

With the u flag, \p{...} matches any character with a given Unicode property: \p{Letter} for any letter in any script, \p{Script=Cyrillic} for a specific script, \p{Number} for any kind of digit. \P{...} negates. Useful for patterns that need to work across natural languages.

Flags

/pattern/gimsuy

The trailing letters of a regex literal — set them in the flags box of this tester. g finds all matches (without it, only the first); i case-insensitive; m makes ^ and $ match line boundaries; s makes . match newlines too; u enables Unicode mode (required for \p{}); y sticky mode (anchors at lastIndex).

Common patterns and what they match

Most regex problems are variants of a small set of common patterns. The table below collects the most useful ones with a working example. Paste the pattern into the tester to see it match the example, then adapt it to your input.

Pattern Matches Example match
\d{4}-\d{2}-\d{2} ISO 8601 date 2026-05-07
\b[\w.+-]+@[\w.-]+\.\w+\b simple email jane.doe@example.com
https?:\/\/\S+ http(s) URL https://example.com/page
#[0-9a-fA-F]{6}\b 6-digit hex color #ff8800
\b[A-Z]{2,}\b all-caps acronym NASA
^\s*$ empty / blank line " "
\b\w+\b a word hello
\b(\w+)\s+\1\b duplicate word the the
\(\d{3}\)\s?\d{3}-\d{4} US phone (123) 456-7890 (415) 555-1212
v\d+\.\d+\.\d+ semver-ish version v1.2.3
^[a-z][a-z0-9-]*$ kebab-case slug my-blog-post
<[^>]+> HTML/XML tag <p class="x">
[\u4e00-\u9fff]+ Han/CJK ideographs 中文
\p{Emoji} (with u) a single emoji 🎉

How matching works under the hood

JavaScript's regex engine is a backtracking NFA — it tries to match the pattern at each position in the input, and when a branch fails, it backs up and tries another. Greedy quantifiers like .* first try to consume as much as possible, then give back characters one at a time when the rest of the pattern fails to match. This is what makes regex expressive — it can handle nested alternation and lookaround — but it is also what makes some patterns catastrophically slow. Catastrophic backtracking happens when a pattern like (a+)+b on input aaaaaaaaaaaaaa tries an exponential number of ways to split the as before failing. If your pattern has nested quantifiers and your input length is unbounded, sanity-check it on adversarial input. The v flag (ECMAScript 2024) introduces set notation and other refinements that make some patterns easier to write safely; this tester accepts the v flag where the browser supports it.

Frequently asked questions

Which regex flavor does this tester use?
JavaScript / ECMAScript. The pattern is compiled with new RegExp(pattern, flags) and matched against your test string in the browser. Most syntax is portable to PCRE (PHP, Python re, Ruby), .NET, Go, and Rust — but advanced features like possessive quantifiers, conditionals, and recursion are PCRE-only and are not supported here.
Why do I only get one match?
Add the g (global) flag. Without it, the engine returns only the first match. With g set, this tester iterates over every match in the test string and highlights all of them. Combine with i for case-insensitive matching: gi.
How do I make <code class="bg-gray-100 px-1 rounded text-xs">.</code> match newlines?
Add the s (dotAll) flag. By default, . matches any character except a line terminator (\n, \r, \u2028, \u2029). With s, it matches any character including newlines.
What's the difference between greedy and lazy quantifiers?
Greedy quantifiers (*, +, ?, {n,m}) match as much as possible while still allowing the rest of the pattern to succeed; lazy ones (suffix any quantifier with ?) match as little as possible. Classic example: <.*> on <a>text</a> matches the whole string; <.*?> matches just <a>.
Can I use lookbehind?
Yes — JavaScript has supported (?<=...) (positive) and (?<!...) (negative) lookbehind since ES2018, and they have been broadly available in all modern browsers since 2020. Lookbehind in JavaScript can have variable length (older PCRE versions only allow fixed-length lookbehind, which is the most common cross-engine portability gotcha).
How do I match a literal special character?
Escape it with a backslash. Special characters in regex are . ^ $ * + ? ( ) [ ] { } | \ /. To match a literal dot, write \.; to match a literal backslash, write \\. Inside a character class, only ^ ] \ - are special and need escaping (and ^ only if at the start, - only if not at the start or end).
Why is my regex catastrophically slow?
You probably have nested quantifiers like (a+)+ or (\w*)*. On input that almost matches, the backtracking engine tries an exponential number of ways to split the input before failing. Fix it by making one of the quantifiers more specific — for example, (a+)+ is equivalent to a+, and the latter is linear. As a rule of thumb, never quantify a group whose body is itself unbounded.
Is the matching done locally?
Yes. The pattern, flags, and test string are all evaluated by the browser's built-in regex engine in your tab; nothing is sent to a server, and the tool works offline once the page has loaded.

Related tools

YAML ↔ JSON
Convert between YAML and JSON
CSV ↔ JSON
Convert between CSV and JSON in either direction
SQL Formatter
Pretty-print SQL with consistent indentation
JSON Formatter
Format, validate, and minify JSON with syntax highlighting
Browse other categories: Word Tools· Number Tools· Text Tools· Converters· Color Tools· Time Tools· Random Generators