🔍 Regex Tester

Test regular expressions live against the JavaScript engine, with a flavor comparison for Python, Java, .NET and PCRE, and catastrophic backtracking warnings.

Free No Signup Required Browser-Based

What Regex Tester Does

A regular expression describes a pattern to match against text. This tester runs your pattern through the browser's own JavaScript engine, so what you see here is exactly what runs in Node or in a browser — and not necessarily what runs in Python, Java, PHP or .NET.

That distinction matters more than most tools admit. Lookbehind, named groups, possessive quantifiers, recursion and Unicode property escapes are all supported unevenly across engines. A pattern that works here can fail, or behave differently, when pasted into a different language.

The other thing worth knowing before you deploy a pattern is that some regular expressions are exponentially slow on inputs that nearly match. That is not a theoretical concern — it is a denial-of-service vector with its own name.

How to Use Regex Tester

  1. Enter your regular expression pattern
  2. Select regex flags (g, i, m, etc.)
  3. Paste or type test text in the input area
  4. View matches highlighted in real-time
  5. See match groups and capture details

Formula Used by Regex Tester

Catastrophic backtracking

nested quantifier over an alternation ⇒ O(2^n) attempts on a failing input

nested quantifier
A repeat inside a repeat, such as (a+)+ or (a|a)*
failing input
A string that almost matches — the engine must try every way to split it before giving up

Worked example

The pattern /^(a+)+$/ tested against a string of "a" characters ending in "!", measured in Node.

  1. 20 characters: 4 ms
  2. 22 characters: 19 ms
  3. 24 characters: 75 ms
  4. 26 characters: 326 ms

Result: Roughly a doubling every two characters. At 40 characters this pattern would take hours. The equivalent safe pattern /^a+$/ completes in under a millisecond.

What Differs Between Regex Flavors

This tool runs the JavaScript engine. If your code runs elsewhere, check these before assuming a pattern transfers.

FeatureJavaScriptPythonJava.NETPCRE
Lookahead (?=)YesYesYesYesYes
Lookbehind (?<=)Yes (ES2018+)Fixed width onlyYesYes, variable widthLimited width
Named groups(?<name>)(?P<name>)(?<name>)(?<name>)(?P<name>) or (?<name>)
Possessive quantifiers a++NoNo (3.11+ yes)YesNoYes
Atomic groups (?>)NoYes (3.11+)YesYesYes
RecursionNoNoNoLimitedYes

Quantifiers and Their Cost

SyntaxMeaningBacktracking risk
a*Zero or more, greedyLow on its own
a+One or more, greedyLow on its own
a?Zero or oneNone
a{2,5}Between 2 and 5Bounded — prefer this
a*?Lazy: as few as possibleLow
(a+)+Nested quantifierExponential — avoid
(a|a)*Alternation with overlap inside a repeatExponential — avoid

Patterns Worth Reusing — and One to Avoid

Tested against the JavaScript engine. Treat all of them as starting points to validate against your own data.

PurposePatternCaveat
Digits only^\d+$Add anchors or it matches a substring
US ZIP^\d{5}(-\d{4})?$Bounded quantifier, safe
Hex color^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
ISO date^\d{4}-\d{2}-\d{2}$Shape only — does not reject 2026-02-31
Slug^[a-z0-9]+(?:-[a-z0-9]+)*$
EmailDo not. The RFC 5322 grammar is not practically expressible; validate by sending a confirmation

How to Read Your Result

Anchors are usually the bug

Without ^ and $ a pattern matches anywhere in the string, so /\d+/ happily "validates" the input "abc123def". Most reported regex failures are a missing anchor rather than a wrong pattern. Anchor behavior is itself a flavor difference: in Python, $ matches before a trailing newline, so a value ending in a newline still passes. JavaScript does not — /^\d+$/ rejects a string ending in a newline unless you add the /m flag.

Prefer bounded quantifiers

a{1,64} cannot backtrack catastrophically the way a+ inside another repeat can, and it also documents your intent. Where you control the input length, bounding both the quantifier and the input is the simplest defense against ReDoS.

Do not validate email addresses with a regex

The address grammar in RFC 5322 permits quoted strings, comments and nested structures that a practical regex cannot express. Every "complete" email regex you find either rejects valid addresses or accepts invalid ones, usually both. Check for an @ with something either side, then send a confirmation link — that is the only validation that proves the address works.

The global flag is stateful

A regex with /g keeps a lastIndex between calls, so reusing the same object across test() calls gives alternating true and false on identical input. It is one of the most confusing bugs in JavaScript regex. Create the pattern fresh, or reset lastIndex, when reusing.

Limitations & Accuracy Notes

  • This runs the browser's JavaScript engine only. Patterns using PCRE recursion, atomic groups or possessive quantifiers will not work here even though they are valid elsewhere.
  • Very slow patterns can freeze the page, because a regex runs synchronously on the main thread. That is the same behavior your server would exhibit — which is the point of the backtracking section above.
  • Matching is Unicode-aware only with the /u flag. Without it, characters outside the Basic Multilingual Plane are treated as surrogate pairs and . matches half of an emoji.
  • The timings quoted were measured in Node on one machine and will vary by engine and hardware. The exponential shape is what matters, not the absolute milliseconds.
  • Regular expressions cannot parse nested structures such as HTML or arbitrarily nested brackets — that requires a parser, not a pattern.

Frequently Asked Questions

What is a regular expression?
A regular expression (regex) is a sequence of characters that defines a search pattern. It is used for string matching, validation, search-and-replace, and text parsing in programming.
What regex flags are supported?
This tool supports all standard JavaScript regex flags: g (global), i (case-insensitive), m (multiline), s (dotAll), u (unicode), and y (sticky).
Which regex flavor does this use?
JavaScript's, since it runs in your browser. That matters for a few things: lookbehind is supported in current browsers but was added late, named groups use the question-mark-angle-bracket syntax, and some constructs from PCRE, Python or .NET — recursion, atomic groups, possessive quantifiers — do not exist here at all.
Why does my pattern match more than I expect?
Quantifiers are greedy by default, so `.*` takes as much as it possibly can and then backtracks. Matching from the first opening tag to the last closing one is the classic symptom. Adding a question mark — `.*?` — makes it lazy and usually fixes it immediately.
What do the flags mean?
g finds every match rather than just the first, i ignores case, m makes the anchors ^ and $ match at line breaks instead of only at the start and end of the whole string, and s makes the dot match newlines too. Forgetting m is the usual reason a multi-line pattern fails.
Do I need to escape a dot inside square brackets?
No. Inside a character class a dot is already a literal dot. Outside one it matches almost any character. Over-escaping inside a class is harmless but it makes patterns much harder to read.
Why is my pattern extremely slow on certain input?
Probably catastrophic backtracking — nested quantifiers such as (a+)+ can make the engine try an exponential number of paths on a string that nearly matches. If a pattern is instant on most inputs and hangs on one, that is the cause, and the fix is usually to make the inner parts more specific so they cannot overlap.
Is my test data sent anywhere?
No. The pattern and the test string are both evaluated in your browser.

References & Further Reading

By OnlineToolHubs Team • September 2026