Skip to main content
ponderloop

Regex Tester

Type a JavaScript regular expression and a test string and see every match highlighted, with its position and its numbered and named capture groups, as you type. The example below, (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) with the g flag, finds 3 matches; the first is “2024-03-15” (year = 2024, month = 03, day = 15), and the replacement $<day>/$<month>/$<year> turns the text into “Released 15/03/2024, patched 02/04/2024 and retired on 31/01/2025.”. Matching runs in a background thread with a 1-second limit, so a runaway pattern is stopped instead of freezing the page. Everything happens in your browser; your text is never uploaded.

Updated Runs in your browser: nothing you enter is uploadedHow this tool works

JavaScript (ECMAScript) syntax. Replace the example: type a pattern and a test string.

Stays in your browser
Flags

Matched on this device and never uploaded or saved. Only the first 200,000 characters are searched, and matching is stopped after one second.

$1 numbered group, $<name> named group, $& the whole match, $$ a dollar sign.

Result

Released 15/03/2024, patched 02/04/2024 and retired on 31/01/2025.

Matches

3 matches

Released 2024-03-15, patched 2024-04-02 and retired on 2025-01-31.
  1. Match 1 index 9, length 10

    2024-03-15
    Group 1 (year)
    2024
    Group 2 (month)
    03
    Group 3 (day)
    15
  2. Match 2 index 29, length 10

    2024-04-02
    Group 1 (year)
    2024
    Group 2 (month)
    04
    Group 3 (day)
    02
  3. Match 3 index 55, length 10

    2025-01-31
    Group 1 (year)
    2025
    Group 2 (month)
    01
    Group 3 (day)
    31

What each flag does

The same pattern and text run without the flag and with it, by this tool. Flag d only adds group positions and u only changes how code points are read, so neither changes which text matches here except where shown.
FlagNameEffectExampleWithout the flagWith the flag
gglobalFind every match, not just the first./\d/ on “a1b2c3”“1”“1”, “2”, “3”
iignore caseTreat upper and lower case letters as equal./cat/g on “Cat cAt”No match“Cat”, “cAt”
mmultiline^ and $ match at every line break, not only at the ends of the text./^\w+/g on “one⏎two”“one”“one”, “two”
sdotAll. also matches line breaks./a.b/g on “a⏎b”No match“a b”
uunicodeMatch whole code points; enables \p{…} property escapes and stricter syntax./^.$/g on “😀”No match“😀”
ystickyOnly match starting exactly where the search begins./b/g on “ab”“b”No match
vunicodeSetsLike u, plus set operations and string properties inside [ ]. Cannot be combined with u./[\p{L}--[a-z]]+/gu on “abcÄÖ”Syntax error: Invalid character class“ÄÖ”
dindicesAlso report where each capture group starts and ends.Shown under each group as “index start to end”No group positionsGroup positions listed

Common pieces of syntax

Each example is run by this tool, so the matches shown are real.
SyntaxMeaningExampleMatches
.Any character except a line break (with s: any character)/a.c/g on “abc a-c”“abc”, “a-c”
\d \w \sA digit, a word character (letter, digit, underscore), a whitespace character/\w\d/g on “a1 b2”“a1”, “b2”
[abc] [^abc] [a-z]One of the listed characters, anything but those, or a range/[^aeiou ]+/g on “regex tester”“r”, “g”, “x”, “t”, “st”, “r”
* + ? {n,m}Zero or more, one or more, zero or one, between n and m repeats (greedy)/o{2,3}/g on “o oo ooo oooo”“oo”, “ooo”, “ooo”
*? +? ??The same repeats, lazy: as few characters as possible/<.+?>/g on “<b>bold</b>”“<b>”, “</b>”
^ $ \bStart of the text (or line with m), end of the text (or line), a word boundary/\bcat\b/g on “cat concat cat.”“cat”, “cat”
( ) (?: )A capture group, and a group that does not capture/(ab)+/g on “ababab ab”“ababab”, “ab”
(?<name> )A named capture group, read back as $<name> or in match.groups/(?<h>\d+):(?<m>\d+)/g on “at 09:30”“09:30”
a|bEither alternative/cat|dog/g on “hotdog catfish”“dog”, “cat”
(?= ) (?! )Lookahead: followed by, or not followed by/\w+(?=;)/g on “a; b c;”“a”, “c”
(?<= ) (?<! )Lookbehind: preceded by, or not preceded by/(?<=\$)\d+/g on “cost $40 or 50”“40”
\1 \k<name>The text a numbered or named group matched earlier/(\w)\1/g on “hello book”“ll”, “oo”
\p{L}A Unicode letter (needs the u or v flag)/\p{L}+/gu on “naïve 123”“naïve”

Replacement patterns

Each template is applied by this tool to the pattern /(?<first>\w+) (?<last>\w+)/ on “Ada Lovelace”.
TokenInsertsExampleResult
$1, $2 … $99The text of that numbered capture group (empty if it did not take part)$2, $1 on “Ada Lovelace”“Lovelace, Ada”
$<name>The text of a named group (only when the pattern has named groups; otherwise it stays as typed)$<last>, $<first> on “Ada Lovelace”“Lovelace, Ada”
$&The whole matched text[$&] on “Ada Lovelace”“[Ada Lovelace]”
$`The part of the text before the match<$`> on “Ada Lovelace”“<>”
$'The part of the text after the match<$'> on “Ada Lovelace”“<>”
$$A literal dollar sign$$$1 on “Ada Lovelace”“$Ada”
$0, $3 (no such group)Left as typed, because there is no group with that number$0|$3 on “Ada Lovelace”“$0|$3”

Limits and safety

LimitValueWhat happens beyond it
Time per run1 secondThe matching thread is stopped and replaced, and the page says the match took too long (possible catastrophic backtracking).
Matches shown1,000Matching stops there and the page says more were found.
Test string200,000 charactersOnly the first part is searched, and the page says so.
Long match or group text300 charactersThe list shows the start followed by “…”; the highlight and replacement use the full text.

How to test a regular expression

  1. Enter the pattern. Type the expression, without the surrounding slashes, in “Regular expression”. A syntax error is explained under the results as you type.
  2. Choose the flags. Tick g to find every match, i to ignore case, m, s, u, v, y or d as needed. They are the same letters you would write after the closing slash.
  3. Paste a test string. Put the text to search in “Test string”. Matches are highlighted in the copy below it and listed with their position.
  4. Read the matches and groups. Each match shows its index and length, then every capture group, numbered and named, or a note when a group did not take part.
  5. Try a replacement. Tick “Replace mode” and type a replacement such as $2 $1 or $<name> to see the replaced text, then copy it.

Frequently asked questions

Which regular expression flavor does this use?
JavaScript’s own, ECMAScript, as implemented by your browser: the page builds a real RegExp object from your pattern and flags. That means lookbehind, named groups, Unicode property escapes and the v flag work if your browser supports them, and the syntax of other flavors (PCRE, Python, .NET) is not accepted where it differs, for example possessive quantifiers, atomic groups and inline modifiers in older browsers.
What is catastrophic backtracking, and why does the page say a match took too long?
Some patterns, such as (a+)+$ on a long run of a’s followed by another letter, make the engine try an exponential number of ways to match before giving up. In a normal page that freezes the tab. Here the match runs in a Web Worker; after 1 second it is stopped, a fresh worker is started, and you get the message “took too long — possible catastrophic backtracking”. Rewrite the pattern so that repeats cannot overlap, for example a+$ instead of (a+)+$.
Is my text uploaded?
No. The pattern and the text are matched in your browser, in a background thread of this page, and are never sent or stored. If you allow analytics, the site records only that the tool was used, never what you typed.
How do I use capture groups in a replacement?
Put $1, $2 and so on for numbered groups, or $<name> for a named group such as (?<year>\d{4}), in the replacement. $& inserts the whole match, $` and $' insert the text before and after it, and $$ inserts a dollar sign. These are the rules of JavaScript’s String.prototype.replace.
Why does my pattern only find one match?
Without the g flag a regular expression stops at the first match. Tick g to find all of them. With the y flag, matching must also begin exactly where the search starts, so y alone finds a match only at the very beginning of the text, and y together with g finds a run of back-to-back matches.
What does a match with an empty text mean?
A pattern like a* or ^ can match zero characters. Those matches are real: the page lists them as empty matches, draws a thin marker where they occur, and, like JavaScript, moves one character on before looking for the next match so it cannot loop forever.
Why is the u or v flag needed for \p{L} or emoji?
Without u or v a regular expression reads text as 16-bit units, so a character outside the Basic Multilingual Plane, such as an emoji, counts as two. With u or v it reads whole code points and unlocks \p{…} Unicode property escapes. The v flag adds set operations like [\p{L}--[a-z]] and cannot be combined with u; choosing one clears the other.
Why do I get a syntax error message?
The browser rejected the pattern when building the RegExp, and the page shows its reason: for example an unterminated group, a nothing-to-repeat quantifier, an invalid escape under the u flag, or a lookbehind your browser does not support. Messages come from your browser, so their wording can differ between Chrome, Firefox and Safari.
Is anything cut off for large inputs?
Yes, to keep the page quick: only the first 200,000 characters of the test string are searched, at most 1,000 matches are listed, and long match or group values are shortened to 300 characters in the list. The page tells you whenever one of these limits applies.

How it works

The pattern and the flags you tick are passed to the browser’s own RegExp constructor, so the result is exactly what that browser’s JavaScript engine would produce; this page adds no matching engine of its own. With the g flag the page calls exec repeatedly and, after an empty match, advances by one code unit (one code point under u or v) as String.prototype.matchAll does; without g it stops after the first match. Group names are read from the pattern text in the order of their opening parentheses, so numbered and named groups can be shown together. Replacement uses the specification’s GetSubstitution rules for $$, $&, $`, $', $n, $nn and $<name>. All of this runs in a dedicated Web Worker. If a run is still going after 1 second, or you change the input while it runs, the worker is terminated and a new one is created, which is the only reliable way to stop a regular expression that is backtracking without end. Highlighting is built from text nodes and mark elements, never from HTML, so pasted markup is shown as text and cannot run.

Sources

All toolsHome & DIY calculators