Free · Fast · Privacy-first

Test JavaScript Regex Online, Real V8 Engine in the Browser

FixTools Regex Tester runs in the browser, which means it uses the same V8 JavaScript regex engine your Node.js backend and web frontend use.

Uses the real browser JavaScript regex engine (V8)

🔒

Supports ES2018+ features: named groups, lookbehinds, dotAll

Test with String.match(), matchAll(), replace(), and split() semantics

Verify Unicode mode behaviour with the u flag

Cost
Free forever
Sign-up
Not required
Processing
In your browser
Privacy
Files stay local
FreeNo signupWhite-label

Add this Regex Tester to your website

Drop the Regex Tester into any page — blog post, product docs, intranet, school portal — with a single line of HTML. Your visitors get the full tool, processed entirely in their browser. No backend, no uploads, no signup.

  • Files stay 100% in the visitor's browser
  • Responsive — adapts to any container width
  • Free forever, no API key needed

Embed code

<iframe
  src="https://www.fixtools.io/developer/regex-tester?embed=1"
  width="100%"
  height="780"
  frameborder="0"
  style="border:0;border-radius:16px;max-width:900px;"
  title="Regex Tester by FixTools"
  loading="lazy"
  allow="clipboard-write"
></iframe>

Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.

JavaScript Regex Features Worth Testing in a Dedicated Tool

JavaScript regex has evolved significantly since ES5. ES2015 added the u (unicode) and y (sticky) flags. ES2018 introduced named capture groups ((?<name>...)), lookbehind assertions ((?<=...) and (?<!...)), the s (dotAll) flag, and Unicode property escapes (\p{...} with the u flag). ES2024 added the v (unicodeSets) flag, which enables set operations and string properties in character classes. Testing patterns that use these features in a browser-based tester is the most reliable way to confirm they work as expected in a JavaScript context, because the tester uses the same ECMAScript implementation as your runtime environment. A flavour-generic tester might accept or reject features that V8 handles differently, giving you false confidence or unnecessary warnings.

The key JavaScript-specific behaviours that differ from other regex flavours include: lastIndex state management when reusing RegExp objects with the g or y flag (a common source of bugs in loop-based parsing), the way String.prototype.replace() uses $1, $2, and named group references like $<name> in replacement strings, the difference between match() and exec() regarding group capture data in global mode, and how matchAll() returns an iterator of match objects each containing the full group data including named groups and the match index. These nuances are impossible to test accurately in a flavour-generic tester but are immediately observable in a browser-based JavaScript tester running the actual V8 engine.

For TypeScript developers, regex patterns are typed as RegExp and string methods that accept RegExp are well-typed in the standard library definitions. The patterns themselves are untyped string literals to the type checker, so runtime testing in a browser-based tool remains the primary verification mechanism for confirming that a pattern produces the expected match structure. If you use the TypeScript noUncheckedIndexedAccess option, named capture groups must be accessed as match.groups?.name rather than match.groups.name, and your pattern must be tested accordingly to understand the match object shape before writing the access code.

Performance pitfalls in JavaScript regex deserve attention because V8 does not implement the linear-time matching algorithms (such as Rust regex or Go regexp) that guarantee polynomial worst case. JavaScript uses a backtracking NFA, which means a poorly written pattern can take exponential time on adversarial input. The classic danger pattern in JavaScript is the nested or overlapping quantifier such as (a+)+ or (a|aa)*b, applied to a string that almost matches. In a browser context the symptom is a frozen tab and an eventual "page unresponsive" dialog. Mitigate this by avoiding nested quantifiers entirely (rewrite (a+)+ as a+), preferring possessive-equivalent unrolled patterns such as [^a]*a, and capping input length before applying user-supplied or dynamically constructed patterns. On the server side, run untrusted regex inside a worker thread with a timeout so a single slow match cannot stall the event loop.

How to use this tool

💡

Enter your JavaScript regex pattern and test string. The tester uses the browser JS engine, so named groups, lookbehinds, and Unicode mode work exactly as they would in your Node.js or browser JavaScript code.

How It Works

Step-by-step guide to test javascript regex online, real v8 engine in the browser:

  1. 1

    Open the Regex Tester

    Navigate to the FixTools Regex Tester using the link on this page. Because the tool runs in the browser, it uses the V8 JavaScript regex engine natively. No configuration is needed to access ES2018 or later features such as lookbehinds, named groups, or dotAll mode.

  2. 2

    Enter your JS regex pattern

    Type or paste your JavaScript pattern into the pattern field without forward slash delimiters or inline flags. Just the pattern content itself. For a named group example, enter (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) and see each named group appear in the match results panel with its label and captured value.

  3. 3

    Set JavaScript-specific flags

    Enable the flags your production code uses: g for global matching with matchAll(), u for Unicode mode to enable property escapes, s for dotAll so the dot matches newlines, or y for sticky matching in parser loops. Each flag changes the engine's behaviour, so test with the exact flag combination your code will use rather than defaulting to g alone.

  4. 4

    Paste your test string

    Enter the string you pass to match(), test(), or replace() in your JavaScript code. For global matching, paste several lines of representative data and enable both g and m flags to see all matches across the full input at once. Check the match results panel for named group values and positions before writing the code that accesses them.

Real-world examples

Common situations where this approach makes a real difference:

Testing a named capture group pattern for date extraction

A developer writes (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) to extract ISO date components from a log string. In the tester, the named groups year, month, and day appear in the match results panel with their respective values. This confirms that match.groups.year, match.groups.month, and match.groups.day will contain the expected strings when the pattern is used with String.prototype.match() in production JavaScript code, before the developer writes the downstream processing logic.

Verifying a lookbehind assertion for currency parsing

A financial data parser needs to extract the numeric value following a currency symbol without including the symbol in the extracted text. The pattern (?<=\$)[\d,]+\.\d{2} uses a positive lookbehind to assert the presence of a dollar sign at the current position without consuming it. Testing against "$1,234.56 USD" in the browser tester confirms that 1,234.56 is captured and the dollar sign is not. The developer also tests a bare number like 1234.56 to confirm it is not captured when the dollar sign context is absent.

Debugging a sticky regex used in a parser loop

A hand-written tokeniser uses the y (sticky) flag to consume tokens from a source string one at a time, advancing lastIndex after each match. A bug causes occasional tokens to be skipped silently. Reproducing the token pattern in the tester with a sample token sequence reveals that the pattern does not account for optional whitespace between tokens. When lastIndex lands on a space character, the next sticky match fails because the pattern expects to start on a token character directly, not on whitespace.

Testing Unicode property escapes for international text classification

A content filter needs to detect strings containing only characters from the Latin script and reject strings mixing scripts. The pattern ^\p{Script=Latin}+$ with the u flag uses a Unicode property escape for script-level character classification. Testing against "Hello" (Latin), "Привет" (Cyrillic), and "مرحبا" (Arabic) in the browser tester confirms the pattern accepts only Latin text and rejects the other two, validating that Unicode property escapes behave correctly in the V8 engine before deploying the filter.

When to use this guide

Use this page when you are writing JavaScript or TypeScript code that uses RegExp and want to verify pattern behaviour using the actual JS engine rather than a generic regex tester that may behave differently.

Pro tips

Get better results with these expert suggestions:

1

Use named capture groups over index-based groups for maintainable code

Named groups (?<name>...) make both replacement strings and extraction code self-documenting. Instead of writing match[1] and match[2] and counting groups, you write match.groups.year and match.groups.month, which communicate intent at a glance. In String.replace(), reference named groups as $<name>. Test both the named capture pattern and the replacement string in the tester to confirm all names resolve to the expected values before embedding them in production code.

2

Reset lastIndex when reusing a RegExp object with the g flag

A common and subtle JavaScript bug: a RegExp literal with the g flag stored in a variable retains its lastIndex between calls. Calling regex.test() or regex.exec() in a loop without resetting lastIndex to 0 before each new input string causes the engine to start mid-string, making every other call fail unexpectedly. Use String.prototype.matchAll() for global matching in loops rather than managing lastIndex manually, or explicitly set regex.lastIndex = 0 before each new input.

3

Enable the u flag when working with emoji or non-BMP characters

Without the u flag, a JavaScript regex treats characters outside the Basic Multilingual Plane as two surrogate pairs. The dot metacharacter matches one surrogate unit rather than one full character, and quantifiers count surrogates rather than code points. This produces incorrect results for emoji, many CJK extension characters, and mathematical symbols. Always enable the u flag when your pattern or test string contains any character outside the standard Latin and Cyrillic ranges to ensure correct character-level matching.

4

Verify replacement string syntax with $<name> in named-group replacements

Named group back-references in JavaScript replacement strings use the $<name> syntax, not \1 (PCRE-style) and not \k<name> (which is the pattern-side back-reference syntax used inside the regex itself). A common mistake is using the wrong syntax form in the replacement string, which causes the literal text "$<name>" or "\k<name>" to appear in the output instead of the captured value. Test your replacement string output in the tester before writing the String.replace() call.

FAQ

Frequently asked questions

Yes. FixTools Regex Tester runs in the browser and uses the browser's native JavaScript (ECMAScript) regex engine, which in Chrome and Edge is V8. This means all modern JavaScript regex features work in the tester: named capture groups, lookbehind assertions, the dotAll (s) and Unicode (u) flags, Unicode property escapes, and the sticky (y) flag. The match results you see in the tester are identical to what you will get in a JavaScript or Node.js runtime using the same engine version.
Use the syntax (?<name>pattern) inside your regex to create a named group. In the match result object returned by String.prototype.match() or String.prototype.matchAll(), access the captured value as match.groups.name. In a String.replace() replacement string, reference it as $<name>. For example, the pattern (?<year>\d{4})-(?<month>\d{2}) captures date parts by name. Test the pattern in the tester to see named groups appear in the match results panel, then write the access code with confidence.
String.prototype.match() with the g flag returns a flat array of match strings but discards all capture group data. String.prototype.matchAll() returns an iterator of complete match objects, each containing the full match, indexed capture groups, named capture groups, and the match index position. Use matchAll() whenever you need capture group values from multiple matches in the same string. The tester with the g flag shows which matches will be returned; use that information to choose the right method for your use case.
JavaScript uses an NFA-based ECMAScript engine with specific rules for alternation ordering, backreference behaviour, and Unicode handling. Key differences from Python: JavaScript does not support possessive quantifiers or atomic groups; Python named groups use (?P<name>...) rather than (?<name>...). Key differences from PHP/PCRE: PCRE supports recursive patterns, conditional patterns, and possessive quantifiers that have no JavaScript equivalent. Always test in a JavaScript-specific tester when writing JS code to avoid surprises from cross-flavour differences.
The sticky flag forces the regex to match only at the current lastIndex position within the string. In the tester, setting the y flag causes the engine to attempt a match starting at position 0. If it succeeds, the match is shown. To simulate advancing lastIndex as you would in a parser loop, you need to run the pattern in your browser's console or in actual code, since the tester always starts from position 0. The tester is still valuable for verifying that the pattern token sequence is correct before you wire it into the parser loop logic.
Unicode property escapes (\p{Property=Value}) match characters based on their Unicode database properties, such as script (\p{Script=Latin}), category (\p{Letter}), or emoji status (\p{Emoji}). They require the u flag and are supported in V8 from Chrome 64 and Node.js 10 onward. Use them when you need to match characters from a specific language script or Unicode general category without enumerating individual character ranges, which would be impractical for scripts like Arabic, Devanagari, or CJK.
Pass a regex as the first argument to String.prototype.split() to split on a pattern rather than a fixed delimiter. For example, str.split(/\s+/) splits on any run of whitespace characters, treating multiple consecutive spaces, tabs, or newlines as a single delimiter. Test the splitting pattern in the tester by observing what the pattern matches: the split will occur at each highlighted match, and any capture groups inside the regex will be included as separate elements in the resulting array.
The v (unicodeSets) flag is supported in V8 from Chrome 112 and Node.js 20 onward. If you are using a modern version of Chrome or Edge as your browser, the FixTools tester will support it natively since it runs the browser engine directly. Enter the v flag in the flag selector and use set operations like [\p{Letter}&&\p{ASCII}] or string properties in your pattern. If the browser version is older, the tester will show an error for unsupported v flag syntax.
If your application compiles regex from user-supplied strings (search features, custom filter rules, configuration files), the user can supply a pattern designed to take exponential time on a chosen input. Three layers of defence apply. First, never call new RegExp() on raw user input without sanitising; restrict allowed metacharacters or, better, expose a safer subset language that compiles to safe regex internally. Second, run the user-supplied pattern inside a Web Worker on the client or a child process on the server, with a wall-clock timeout that terminates the worker if a single match exceeds a few hundred milliseconds. Third, use a static analyser such as safe-regex2 or recheck to reject dangerous patterns at compile time, before they reach production.
Two failure modes are common. The first is catastrophic backtracking against a longer input than you tested in the browser: a pattern that runs in 5 milliseconds against a 100-character input may take 30 seconds against a 1000-character input if the worst-case is exponential. Profile with longer realistic inputs in the tester before deploying. The second is hitting V8's internal recursion limits on patterns that use deeply nested groups or massive alternation lists. The fix is the same in both cases: simplify the pattern to remove ambiguous overlap between quantifiers, prefer flat alternation lists over nested grouping, and cap input length before applying the pattern.

Related guides

More use-case guides for the same tool:

Ready to get started?

Open the full Regex Tester — free, no account needed, works on any device.

Open Regex Tester →

Free · No account needed · Works on any device