Regex Tester

Test regular expressions with live match highlighting.

About this tool

Write a JavaScript regular expression, toggle flags and see every match highlighted as you type, together with capture groups and a replace preview.

How to use it

  1. Type a regular expression in the pattern field, without the surrounding slashes.
  2. Toggle flags: g for all matches, i to ignore case, m for multiline anchors, s so . matches line breaks, u for Unicode.
  3. Paste test text and see every match highlighted, with capture groups listed below.
  4. Turn on Replace to preview a substitution using $1, $2 or $<name>.

Questions

Which regex flavour is this?
JavaScript (ECMAScript). It is very close to PCRE and Python for everyday patterns, but lookbehind support, named group syntax and some escapes differ between languages.
How do I match a literal dot or bracket?
Escape it with a backslash: \. matches a dot, \( a parenthesis, \[ a bracket. Inside a character class like [.] most characters lose their special meaning.
What is the difference between .* and .*?
.* is greedy and matches as much as possible; .*? is lazy and matches as little as possible. Lazy matching is what you usually want when extracting text between two markers.
How do named groups work?
Write (?<name>...) to capture into a named group. Its value is shown in the match details and you can use it in a replacement as $<name>.
Why does my regex match an empty string?
A pattern where everything is optional, such as a* or (\d+)?, can match zero characters, and it does so at every position where nothing longer fits. The Match details table shows these matches as (empty). Use + instead of *, or make at least one part of the pattern required.
How do I use the whole match in a replacement?
Write $& for the entire match, $1 and $2 for numbered groups, $<name> for named groups and $$ for a literal dollar sign. For example, replacing \d+ with [$&] wraps every number in square brackets. Turn on the g flag to replace every occurrence rather than only the first.
Can a regex freeze the browser?
Yes. Nested quantifiers such as (a+)+ or (\w+\s?)*$ can backtrack exponentially on text that almost matches, which is known as catastrophic backtracking. Matching runs in your browser tab, so the page may hang until you close it. Rewrite the pattern so each character can be matched in only one way, for example a+ instead of (a+)+.

Regex flags explained: g, i, m, s and u

Regex flags change how the whole pattern behaves. g (global) finds every match instead of stopping at the first. Without it, this tester highlights only the first match and Replace changes only the first occurrence, exactly like String.replace in JavaScript. i ignores case, so /error/i matches Error and ERROR. m makes ^ and $ match at the start and end of every line, which you need when testing a pattern against a log file.

The s flag, called dotall, lets . match line breaks too, so <p>.*?</p> can span several lines. The u flag turns on Unicode mode: emoji and other characters outside the Basic Multilingual Plane count as one character, Unicode property escapes become available, and unknown escapes such as \- outside a character class become errors instead of being silently accepted. The sticky y flag and the d flag for match indices are not offered here.

How to test a regex against real data

Test a regular expression against realistic samples, not just the happy path. Paste text that includes values that should match and values that shouldn’t, then watch the highlighting. For an ISO date, start with \d\d\d\d-\d\d-\d\d and check that 2026-11-08 lights up while 2026-1-8 doesn’t. Then notice that 12026-11-08 still matches partly. Adding \b word boundaries, or ^ and $ with the m flag, fixes that.

The Match details table lists every match with its index and capture groups, numbered $1, $2 and so on, plus named groups by name, which is the quickest way to check that a group captures what you expect. For email addresses, accept that no practical regex fully follows the RFC: a pattern like [\w.+-]+@[\w-]+\.[\w.-]+ catches typos, and a confirmation email does the real check. To take a URL apart, use URL Encode, Decode and Parse instead.

Using a tested regex in JavaScript, Python and grep

A pattern tested here can go straight into a JavaScript regex literal such as /\d+/g without extra escaping. When you build it from a string, as with new RegExp() or in most other languages, every backslash must be doubled, so \d+ becomes "\\d+" inside a normal string literal. Python raw strings like r"\d+" and Go backtick strings avoid the doubling. Forgetting it is the most common reason a regex works in a tester but not in code.

Flags live in different places in other languages. Python uses re.IGNORECASE or an inline (?i), and grep uses -i for case, with -E or -P selecting the syntax. Lookbehind also differs: JavaScript allows variable-length lookbehind, while the Python re module requires a fixed width, so (?<=\$|USD )\d+ fails there. The grep and ripgrep Command Builder turns a tested pattern into a ready-to-run command with every flag explained.

Something not working, or a result looks wrong? Report a problem with this tool