Skip to content
DeveloperRuns in your browserPopular

Regex Tester

Test regular expressions against sample text with live highlighting in this regex tester.

Input
No upload needed — instant
Privacy
Nothing is uploaded
Cost
Free · no sign-up · no watermark

Loading tool…

The tool is loading its code on your device. This happens once and is cached for later visits.

Processed entirely on your device

Everything you type or paste is handled by JavaScript running in this tab. No request is sent, nothing is logged and nothing is stored. Close the page and it is gone.

Overview

About the Regex Tester

Free online regular expression tester with live match highlighting, capture group inspection, a replacement preview, a cheatsheet and plain-English explanations.

A regular expression is a program, and like any program it needs testing before deployment. That is exactly what a regex tester is for. The difference is that regex bugs are unusually silent: a pattern that matches slightly too much or slightly too little produces plausible-looking output that is quietly wrong. A regex tester with live highlighting turns that silent failure into something you can see on every keystroke.

This online regex tester runs JavaScript-flavoured patterns against your own sample text: matches highlight as you type, capture groups break out with their exact spans, a replacement preview shows the substituted output before you commit it, and a step budget guards against the catastrophic backtracking that freezes lesser tools.

Building a regex pattern deliberately

The reliable method is incremental. Start with a literal substring that appears in a real match. Widen it one character class at a time, checking the highlight after each change. When it matches everything you want, add anchors and boundaries to exclude what you do not want. Writing a full pattern from memory and then debugging it is far slower than growing one that works.

The regex flags that matter most

g — global. Without it, most languages return only the first match. With it, they return all. Forgetting g in a replace operation is the classic "it only fixed the first one" bug.

i — case-insensitive. Useful for user-facing text. Dangerous for identifiers, where case carries meaning.

m — multiline. Redefines ^ and $ as line boundaries. Essential when processing a document line by line with a single pattern.

s — dotAll. Lets . match \n. Without it, .* stops at the end of a line, which surprises almost everyone the first time.

u — Unicode. Enables \p{...} property escapes and correct surrogate-pair handling. Use it whenever the input may contain emoji or non-BMP characters.

Character classes worth memorising

ClassMatches
\dDigit 0–9 (equivalent to [0-9])
\wWord character: letters, digits, underscore
\sWhitespace: space, tab, newline, form feed
\bWord boundary — zero width
.Any character except newline (unless s flag)
[^abc]Any character except a, b or c
\p{L}Any Unicode letter (requires u flag)

Each has an uppercase negation: \D, \W, \S.

Greediness is the default in regular expressions

Quantifiers are greedy. <.+> applied to <a><b> matches the entire string, because + consumes everything it can and only backtracks as far as necessary to satisfy the final >. If you wanted each tag separately, you need <.+?>.

The mental model: greedy means "take as much as possible, then give back until it works". Lazy means "take as little as possible, then take more until it works". Both arrive at a match; they arrive at different ones.

Lookaround in regular expressions

  • (?=...) positive lookahead — what follows must match, but is not consumed.
  • (?!...) negative lookahead — what follows must not match.
  • (?<=...) positive lookbehind — what precedes must match.
  • (?<!...) negative lookbehind — what precedes must not match.

Lookaround is the tool for matching a position based on context: a password containing a digit without consuming it, a price not preceded by a currency symbol, a word not followed by a comma.

Performance and catastrophic backtracking

Backtracking engines explore alternatives, and nested quantifiers multiply them. (a+)+b against aaaaaaaaaaaaaaaaac takes exponential time because the engine tries every possible way to partition the a's before concluding failure. If a pattern hangs on a non-matching input, that is what is happening. Restructure to remove the ambiguity, or use an engine with atomic groups or possessive quantifiers.

Testing a regex replacement before you ship it

A replacement is a second program riding on the first, and it deserves the same testing. $1, $<name> and $$ all behave differently across engines, and a pattern that captured correctly can still produce a mangled substitution when the replacement references a group that did not participate in the match. The replacement preview in this regex tester shows the final output against your real sample text, so the difference between what you meant and what you wrote is visible before it reaches a codebase. Test the pattern, then test the replacement, then ship.

A regex checker that keeps up as you type

Feedback speed is the whole value of an online regex tester. Every keystroke re-runs the pattern against the full sample and re-highlights the matches, so widening a character class or tightening an anchor shows its effect immediately rather than after a batch run over production data. When a pattern is slow, the step budget reports it instead of hanging the tab — which is also a useful warning about how that pattern will behave on a much larger input in the real system.

Common patterns people test here

  • Emails, URLs and slugs — the classics, always slightly wrong on the first attempt.
  • Date and number formats — capture groups for day, month and year, or thousands separators.
  • Log line parsing — extracting timestamps, severity levels and message bodies from raw logs.
  • Password rules — lookaheads asserting digit, upper-case and symbol requirements at once.
  • Search and replace at scale — verifying a substitution before running it over hundreds of files.

Each of these is faster to build incrementally in a regex tester than to write blind and debug from the results of a failed run.

Step by step

How to use the Regex Tester

  1. Type your pattern into the expression field.

  2. Set the flags you need — g for global, i for case-insensitive, m for multiline, s for dotAll.

  3. Paste sample text into the test area; matches highlight as you type.

  4. Inspect each match's index, length and capture groups in the results panel.

  5. Try a replacement string and preview the substituted output before using it.

Why use it

Benefits and common use cases

What this tool is good for, and what it deliberately does not try to do.

Live highlighting as you type

Matches update on every keystroke, so you see immediately whether a change widened or narrowed the pattern rather than discovering it after a batch run.

Full capture group breakdown

Every match lists its named and numbered groups with their exact spans, which is where most of the real work in regex debugging happens.

Replacement preview

Test $1, $<name> and $$ substitutions against your sample text and see the final output before committing the change to your codebase.

Catastrophic backtracking guard

Execution runs with a step budget, so a pattern that would hang your editor reports the problem instead of freezing the tab.

Questions

Frequently asked questions

Short, honest answers about quality, limits and privacy.

What do the regex flags mean?

g finds all matches rather than stopping at the first. i ignores case. m makes ^ and $ match at line boundaries instead of only the string start and end. s lets . match newline characters (dotAll). u enables correct Unicode handling. y makes matching sticky at lastIndex. The most common combination is gi.

What is the difference between greedy and lazy quantifiers?

A greedy quantifier (*, +, ?, {n,}) consumes as much as possible then backtracks until the rest of the pattern matches. Appending ? makes it lazy, consuming as little as possible. In '<a><b>', /.*/ matches the whole string while /.*?/ matches nothing — and /<.*>/ matches '<a><b>' while /<.*?>/ matches just '<a>'.

Why is my regex suddenly extremely slow?

Catastrophic backtracking. It happens when nested quantifiers can split the same input many ways — classic examples are (a+)+ or (.*.*)* — and the engine explores an exponential number of paths before failing. Restructure with atomic groups, possessive quantifiers, or simply remove the nesting.

Are named capture groups supported?

Yes. Write (?<year>\d{4}) to capture into a group called year, then reference it as $<year> in a replacement or match.groups.year in JavaScript. Named groups make complex patterns dramatically more readable.

Will my regex behave identically in every language?

No. The core syntax is shared, but details diverge: lookbehind support, Unicode property escapes, named group syntax, whether \d matches non-ASCII digits, and default greediness in some engines. Always test in the engine you will actually deploy to.