Regex Tester

Write regular expressions and test them against your text in real time. Highlights matches instantly.

Updated July 11, 2026

100% Private & Secure

This tool runs in your browser.
Your data is never uploaded or stored.

Test String

How to use

  1. 1

    Enter your regular expression.

  2. 2

    Enter the test string.

  3. 3

    See highlighted matches in real time.

When to use it

Building and refining a validation pattern

Iterate on patterns like emails, phone numbers, or slugs against real samples. Live match highlighting shows exactly which substrings hit, so you can tighten quantifiers or anchors before shipping the pattern into a form validator.

/^[a-z0-9-]{3,48}$/ tested against "my-cool-post" and "My Post!"

Extracting structured data from logs

A capture group over a log line pulls out timestamps, levels, and request IDs without writing a full parser. The tool lists every match and its groups, which is faster than eyeballing raw lines.

Porting a regex across languages

Python or PCRE patterns often use features JavaScript lacks (named groups with (?P<name>), recursion). Testing the pattern here surfaces unsupported syntax before it breaks a browser at runtime.

Debugging catastrophic backtracking

Patterns like (a+)+b on a long "aaaa..." input can hang the engine. Feeding the suspected pattern with progressively longer inputs makes the slowdown visible so you can rewrite it as an unambiguous alternative.

How it works

Literals vs new RegExp(), and why it matters

JavaScript gives you two ways to create a regexp. A literal /abc/gi is compiled once when the script loads and is immune to string-escaping bugs. The constructor new RegExp("abc", "gi") takes a string, which means you must double-escape backslashes ("\\d" for a digit) — but it is the only option when the pattern is built at runtime from user input or configuration.

Beware of the literal-as-state trap: a literal with the g or y flag carries a mutable lastIndex. Calling .test() repeatedly on the same literal alternates between true and false because the search resumes from the previous offset.

  • Use a literal for fixed patterns — cleaner syntax, no escaping headaches
  • Use new RegExp only when the pattern is dynamic or config-driven
  • Reset lastIndex = 0 before reusing a global/sticky regexp with .test()

Flags, the u flag, and the newer v flag

Flags change how the engine interprets and searches a pattern. g finds all matches instead of stopping at the first; i ignores case; m makes ^ and $ match line boundaries; s lets . match newlines; y anchors each match at lastIndex.

The Unicode-sensitive flags are the ones most people miss. Without u, a regexp treats its input as UTF-16 code units, so emoji and astral characters like 🎉 (U+1F389) are seen as a surrogate pair/.{1}/ matches only the first half. Adding the u flag switches to code-point semantics, so \u{1F389} and . behave correctly.

  • u — code-point semantics; required for \u{...} escapes and emoji handling
  • v (Unicode sets, standardized in ECMAScript 2024) — a superset of u that adds set operations and properties of strings
  • With v, you can intersect two Unicode properties in one class
// v flag: letters that are NOT ASCII
const re = /[\p{Letter}&&[^a-zA-Z]]/v;
re.test("é"); // true
re.test("a"); // false

Backreferences, lookahead, and the ReDoS trap

A backreference like \1 matches the exact text a capture group consumed earlier — useful for matching paired quotes ((['"])(.*?)\1). Lookahead (?=...) and lookbehind (?<=...) assert what comes before or after a position without consuming it. JavaScript supports both, with variable-length lookbehind since ES2018.

The danger is catastrophic backtracking: when two quantifiers overlap, the engine tries an exponential number of ways to split the input before failing. This is the basis of regular-expression denial-of-service (ReDoS) attacks. The fix is to make patterns unambiguous — write [^,"]+ instead of .*? between delimiters, and prefer negated character classes over greedy . when you know the boundary.

Common mistakes & edge cases

Problem

A pattern works in Ruby or Python but throws "Invalid regular expression" in JS

Fix

Features like (?P<name>...) (Python), \R, or recursion are not in the ECMAScript spec. Use (?<name>...) for named groups, and test the ported pattern here first.

Problem

An emoji is matched twice, or ^.$ fails on a single emoji

Fix

You are missing the u flag. Without it, the engine sees surrogate halves. Add u (or v) so the pattern works on code points, not code units.

Problem

.test() returns true, then false, then true on the same string

Fix

A g-flagged regexp keeps lastIndex across calls. Either reset re.lastIndex = 0, remove the flag, or use String.prototype.match instead.

Problem

The browser tab freezes on long input

Fix

Catastrophic backtracking. Rewrite nested or overlapping quantifiers (e.g. (a+)+) as a single unambiguous class like a+, or use atomic grouping equivalents.

Frequently Asked Questions

Which regex flavor does this support?
This tool uses JavaScript regex syntax.

References & further reading

Related reading

Related Tools

View all tools