Skip to content
Tooletto

Regex Tester

Test JavaScript regular expressions against sample text with live highlighting, capture groups, named groups and a replace preview. Runs entirely in your browser.

  • Files never leave your device
  • Free, no signup
  • No watermarks
  • Works offline once loaded
Loading tool…

How to regex tester

  1. 1

    Enter your pattern

    Type the expression and pick the flags you need.

  2. 2

    Add test text

    Matches highlight as you type, with every capture group listed.

  3. 3

    Try a replacement

    The replace tab previews the result using $1 style references.

Why live highlighting beats reading a pattern in your head

A regular expression is genuinely difficult to mentally trace against real text — a pattern like `(\d{3})-(\d{2})-(\d{4})` is readable enough as an abstract description, but confirming it matches exactly the substrings intended, and only those, against a specific block of sample text is a different kind of check than reading the pattern and reasoning about it. Highlighting every match directly on the sample text as the pattern is typed turns that abstract reasoning into a concrete, immediate visual confirmation — matches either appear where expected or they do not, with no mental simulation required.

This becomes especially valuable for anything using lookahead, lookbehind, or non-greedy quantifiers, where the actual matched boundaries are frequently not what someone would guess from reading the pattern alone. Seeing exactly where a match starts and ends, rather than assuming, catches an off-by-one boundary error immediately rather than after it has shipped inside a validation function.

JavaScript regex is not the same language as PCRE or Python's re

Regular expression syntax looks broadly similar across languages, but the specific features supported differ in ways that matter once a pattern uses anything beyond the basics. JavaScript lacks possessive quantifiers and atomic groups, both of which exist in PCRE (used by PHP and many other tools) as ways to prevent certain backtracking patterns explicitly. Lookbehind assertions, now supported in JavaScript, arrived considerably later than lookahead did and were unavailable in older browser versions, which still occasionally matters for code that has to run on legacy environments. And `\d` in a JavaScript pattern matches only ASCII digits 0–9 unless the pattern also carries the `u` (Unicode) flag, which surprises anyone assuming it behaves the same as a Unicode-aware digit class in another language's regex engine. Testing a pattern intended for JavaScript specifically, rather than copying an example written for Python or a shell tool, is what this tool is built around.

Catastrophic backtracking, and why the tester has a time budget

Certain regex patterns — most commonly ones with nested quantifiers, like `(a+)+b` — have a pathological property where, against a long string that ultimately does not match, the engine explores an exponentially growing number of ways to backtrack before giving up. A pattern that returns instantly against a ten-character non-matching string can take longer than the age of the universe against a fifty-character one, which is not an exaggeration but the literal mathematical behaviour of exponential growth. This is a real, exploitable vulnerability class in production systems — a ReDoS, or Regular Expression Denial of Service — where an attacker who can control the input string to a vulnerable pattern can hang a server process indefinitely with a single request.

This tool aborts evaluation after a short time budget specifically so a pattern with this property freezes the test session rather than the browser tab entirely, and hitting that abort is itself useful information: it means the pattern likely has this exact vulnerability and needs restructuring, typically by making an inner quantifier more specific so the ambiguity that causes exponential backtracking cannot arise in the first place.

Frequently asked questions

Which regex flavour is this?

JavaScript (ECMAScript), which is what runs in your browser. It differs from PCRE and Python in places — no lookbehind in very old browsers, no possessive quantifiers or atomic groups, and `\d` matches only ASCII digits unless you use the `u` flag.

What does the global flag actually change?

Without `g`, only the first match is found. With it, every match is returned — which is what you want for highlighting or replacing throughout a document. This tool shows all matches regardless, but the flag still affects how `replace` behaves.

Why did my pattern time out?

Some patterns backtrack catastrophically — nested quantifiers like `(a+)+b` can take exponential time on a non-matching string. The tool aborts after a short budget rather than freezing your tab. If it happens, the fix is almost always to make the inner quantifier more specific.

How do I use capture groups in a replacement?

Reference them as `$1`, `$2` and so on, or `$<name>` for named groups written `(?<name>…)`. Use `$&` for the whole match and `$$` for a literal dollar sign.