Skip to main content

Regex Tester

Live match highlighting, group inspection and replace preview, with risk warnings

Highlight every match live and mark where each one startsList capture and named groups, marking groups that did not participateReplace preview supports the full
amp;, $1 and
lt;name> reference syntax
Built-in catastrophic backtracking warnings so the browser is not frozen
//g

Matches3 match(es)

  • order-2024-03-15Position: 0
    Group 1: 2024Group 2: 03Group 3: 15
  • order-2024-03-18Position: 25
    Group 1: 2024Group 2: 03Group 3: 18
  • order-2024-04-02Position: 50
    Group 1: 2024Group 2: 04Group 3: 02

Highlight preview

order-2024-03-15 id:8823
order-2024-03-18 id:9911
order-2024-04-02 id:1042
amp; (whole match), $1 (group),
lt;name> (named group)" spellCheck="false" class="bg-card border-border focus:border-primary h-11 w-full rounded-xl border px-4 font-mono text-[13px] outline-none transition-colors" value="$1/$2/$3"/>

Replaced result

2024/03/15 id:8823
2024/03/18 id:9911
2024/04/02 id:1042

Syntax reference

  • \dA digit 0-9
  • \wA letter, digit or underscore
  • \sA whitespace character
  • .Any character (not newline by default)
  • ^Start of the string or line
  • $End of the string or line
  • *The previous item, 0 or more times
  • +The previous item, 1 or more times
  • ?The previous item, 0 or 1 times
  • {n,m}The previous item, n to m times
  • [abc]Character class - matches any one of them
  • (a|b)Alternation - matches a or b
  • (?:...)Non-capturing group, takes no group number
  • (?<name>...)Named group, referenced as
    lt;name>
  • (?=...)Positive lookahead, consumes nothing
  • (?<=...)Positive lookbehind, consumes nothing

Last updated: 2026-10-10

About this tool

The most time-consuming part of writing a regex is always the trying - you try it, discover a bracket is missing, fix that, then find that greedy matching swallowed something it should not have. This tool puts the matches, capture groups, positions and replacement result on screen at the same time, so changing one character shows you every consequence at once instead of printing to the console over and over.

Features

Live highlighting and positions

Results update the moment you edit the pattern, with matched fragments highlighted directly. Every match reports its start index, and for mixed Chinese/English text also a code-point index - the latter being the cursor position you actually see in an editor.

Complete group information

Every capture group is listed with its value. Optional groups that did not participate are shown explicitly as “did not participate” rather than left blank, which matters a great deal when debugging a complex pattern. Named groups show their name alongside.

Replace preview

Supports

amp; (whole match), $1 (numbered group) and
lt;name> (named group), showing the fully replaced text live so you do not have to copy it elsewhere to try it out.

Six freely combinable flags

Global, ignore case, multiline, dot-all, Unicode and sticky, each with its own toggle, and the resulting flag string is shown live.

Catastrophic backtracking warnings

Nested quantifiers such as (a+)+ make the number of backtracking steps grow exponentially and can easily freeze a browser. The tool recognises and warns about these structures, and enforces an execution time budget, aborting on timeout.

Automatic protection for long input

Both the match count and the text length have limits, and hitting one produces an explicit “truncated” notice rather than silently dropping results or letting the page stop responding.

How to use

  1. 1

    Enter the pattern

    Type into the expression box - you do not need the surrounding slashes. Syntax errors are reported immediately, including which position is at fault.

  2. 2

    Choose flags

    Tick the flags you need. Most cases need “global” to see every match; when working with Chinese text it is worth enabling Unicode mode as well.

  3. 3

    Paste the test text

    Paste in real text - real data surfaces edge cases far better than constructed examples, such as a leading newline or trailing space.

  4. 4

    Check groups and replacement

    Compare the group values to confirm your captures are right, then use the replacement box to verify the rewrite you expect. Once both look correct, copy the pattern into your code.

Options

g (global)
Finds every match rather than just the first. With this on, the results list every match.
i (ignore case)
Ignores letter case while matching, so /abc/i matches ABC.
m (multiline)
Makes ^ and $ match the start and end of each line rather than of the whole string. Almost always needed when processing multiline logs.
s (dot matches newline)
Lets . match newline characters too. By default . does not, which is why so many people find their pattern will not match across lines.
u (Unicode)
Treats the pattern in terms of Unicode code points rather than UTF-16 code units. Only with this on can you use escapes like \u{1F600}; enable it for emoji and rare CJK characters.
y (sticky)
Matches starting from lastIndex and must succeed exactly there. Useful for writing tokenisers.
Start position
The index of the matched fragment in the text. For mixed Chinese/English text a code-point index is shown as well, matching character positions in an editor (an emoji counts as one).

Common use cases

  • Verifying validation patterns for phone numbers, emails, national IDs and the like
  • Extracting timestamps, IPs and error codes from logs in bulk
  • Debugging \b and greedy quantifiers to confirm boundaries behave as expected
  • Testing the effect of replacement rules, such as bulk renaming
  • Checking how a pattern behaves under different flag combinations
  • Confirming group numbering so $1 and $2 are not used in the wrong place
  • Working out why ^ and $ fail to match in multiline text

FAQ

Questions you may have about this tool

Why will my pattern not match across lines?

Because by default . does not match newline characters. There are two fixes: enable “dot matches newline” (the s flag) so . can match line breaks, or use a character class such as [\s\S], which includes newlines by construction and needs no flag. The former is more concise, the latter more portable.

Why do ^ and $ not match where I expect?

By default ^ matches only the very start of the string and $ only the very end. If your text has multiple lines and you want each line’s start and end, enable “multiline” (the m flag). Forgetting this flag when processing logs is the single most common mistake.

What is catastrophic backtracking?

When a pattern contains nested quantifiers such as (a+)+, the cost of a single failed match grows exponentially with input length. Twenty characters may take only a few thousand attempts, but thirty characters pushes into the hundreds of millions and the browser freezes completely. This tool detects these structures and warns about them, and sets a time budget per match.

What is the difference between greedy and lazy quantifiers?

Greedy (the default) matches as much as possible; lazy (a trailing question mark, such as .*?) matches as little as possible. Given `a"b"c`, the pattern ".*" matches the outermost pair of quotes while ".*?" matches the nearest pair. The former is used more often when you need to span several candidates, the latter for extracting what sits between a pair of delimiters.

How is group numbering worked out?

Groups are numbered from 1 in the order their opening brackets appear. Non-capturing groups of the form (?:...) take no number, so in (?:a)(b) the b is group 1. Named groups (?<name>...) are recommended: more readable, and they do not break when you reorder the pattern.

Why is a group shown as “did not participate”?

Because a branch in the pattern (such as (a)|(b)) takes only one path at any given match, so the group on the other path has no value. The tool marks this explicitly rather than leaving it blank, so you can distinguish “the group exists but did not match” from “the group does not exist”.

What does the Unicode flag (u) do?

It makes the pattern work in terms of Unicode code points rather than UTF-16 code units. The most visible consequence: without it an emoji counts as two characters and quantifiers or character classes may behave incorrectly; and only with it can you use code-point escapes such as \u{1F600}. Enable it when handling Chinese text and emoji.

Are my matches uploaded?

No. Matching and replacement are performed entirely by your browser’s own regex engine on your machine, with no network requests. Testing production logs leaks nothing - though it is still worth masking keys and phone numbers in those logs.