Skip to content
DeveloperRuns in your browserPopular

Regex Tester

Test regular expressions against sample text with live highlighting.

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. 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.

Building a 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 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

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

  • (?=...) 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

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.

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.