Regex Tester & Debugger

Evaluate regular expression patterns against multi-line test strings in real time. Inspect exact match boundaries, extract numbered and named capture groups, simulate string substitutions, and export idiomatic regex code across major programming runtimes.

Regular Expression Pattern/gd
//gd
Test Stringmatches
Length194 chars
Lines3
Matches4
1Match #1[28..48] · 20 chars
support@codekivo.com
$1<user>
"support"
$2<domain>
"codekivo.com"
2Match #2[52..71] · 19 chars
sales@enterprise.io
$1<user>
"sales"
$2<domain>
"enterprise.io"
3Match #3[100..126] · 26 chars
alex.dev_99@sub.domain.org
$1<user>
"alex.dev_99"
$2<domain>
"sub.domain.org"
4Match #4[130..147] · 17 chars
contact@gmail.com
$1<user>
"contact"
$2<domain>
"gmail.com"

All regex evaluations run 100% locally in your browser — your test data and patterns never leave your device.

Step-by-Step Evaluation Workflow

Step 1

Define Expression and Flags

Input your regular expression pattern between the delimiters /.../ and configure required modifiers such as global (g), case-insensitive (i), multiline (m), dotAll (s), Unicode (u), or indices (d).

Step 2

Supply Target Input Text

Paste, type, or drag and drop log payloads, code snippets, or configuration files into the Test String panel to initiate immediate evaluation.

Step 3

Inspect Token Matches and Groups

Examine color-coded inline highlights alongside exact character offsets, capture group values, and named capture group dictionaries in the inspector panel.

Step 4

Test Substitutions and Export Code

Verify replacement strings using reference tokens ($1, $&, $<name>) and export production-ready syntax snippets for JavaScript, Python, Go, PHP, or Java.

Production Pattern Blueprints

Battle-tested expressions with named capture groups for parsing, validation, and data extraction:

1. RFC 5322 Email Extraction

Flags: /g

Isolates recipient mailbox into <user> and host into <domain>, supporting subdomains and tags (+v2).

Regular Expression
/(?<user>[a-zA-Z0-9._%+-]+)@(?<domain>[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/g
Sample Match Payload
Operations: ops@codekivo.com, triage: bug-report+v2@sub.cluster.internal

2. RFC 3986 URI & Endpoint Deconstruction

Flags: /g

Deconstructs web addresses into distinct named components: host authority, optional port number, resource route path, and raw query string.

Regular Expression
/https?:\/\/(?<host>[a-zA-Z0-9.-]+)(?::(?<port>\d+))?(?<path>\/[^\s?#]*)?(?:\?(?<query>[^\s#]*))?/g
Sample Match Payload
Endpoint: https://api.service.internal:8443/v2/metrics?filter=active&limit=50

3. ISO 8601 Timestamp with Timezone Offset

Flags: /g

Matches UTC Zulu notations (Z) and explicit directional hour offsets (+02:00) across high-throughput log streams.

Regular Expression
/(?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(?:Z|[+-]\d{2}:?\d{2}))/g
Sample Match Payload
2026-09-16T17:55:00.124Z [INFO] Service worker heartbeat ack at 2026-09-16T18:00:00+02:00

4. SemVer 2.0.0 Release Specification

Anchored

Enforces positive integer versions without leading zeroes while parsing optional prerelease channel identifiers and build metadata.

Regular Expression
/^v?(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\+(?<build>[0-9A-Za-z.-]+))?$/
Sample Match Payload
v2.14.0-rc.3+build.892

JavaScript (ECMAScript) Regex Flags Reference

Modifiers change how the regular expression engine steps through input memory and matches boundaries:

FlagIdentifierEngine Behavior & Execution Characteristics
gGlobalIterates across the entire string buffer. The engine mutates the lastIndex property on the RegExp instance after each match instead of halting at index 0.
iIgnore CaseEnforces case-folding character comparison. Both ASCII and Unicode character sets match irrespective of casing variations without duplicating uppercase and lowercase ranges.
mMultilineAlters line boundary anchors: ^ matches line starts (\n or \r) and $ matches line ends, rather than strictly matching the entire buffer boundaries.
sDotAllExpands wildcard dot (.) semantics to match newline and carriage return characters (\n, \r, \u2028, \u2029).
uUnicodeProcesses the pattern as a sequence of 32-bit Unicode code points. Correctly navigates UTF-16 surrogate pairs (e.g. emoji and mathematical symbols) and activates \p{Property} escapes.
yStickyRestricts pattern matching to start precisely at the offset specified by lastIndex. Does not scan subsequent characters if the match fails at that exact index.
dIndicesGenerates start and end offset index arrays (match.indices) for the complete pattern match and every capturing group (ES2022 specification).
vUnicode SetsUpgrades u flag with character class set operations (intersection &&, subtraction --) and string property support (ES2024).

Engine Architecture: Traditional NFA vs DFA Matching Paradigms

Browser JavaScript engines execute regular expressions using a Traditional Non-Deterministic Finite Automaton (NFA) engine. Understanding its internal execution model clarifies why certain features exist and where performance cliffs occur:

Expression-Directed Traversal

NFA engines step through the pattern tokens one by one, attempting to match each token against the current character in the target text. If a branch fails, the engine unwinds to the last saved checkpoint and tries alternative paths.

Backtracking State Stack

When encountering greedy quantifiers (*, +) or alternations (|), the engine pushes backtrack positions onto an internal stack. This mechanism allows lookaheads, lookbehinds, and captured backreferences.

DFA Determinism Comparison

In contrast, text-directed DFA engines (like Go's RE2) scan each character once simultaneously across all possible states. While DFAs guarantee strict O(n) linear execution time, they cannot implement lookaround or backreferences.

Catastrophic Backtracking (ReDoS) Anatomy & Safe Refactoring

Regular Expression Denial of Service (ReDoS) occurs when an NFA engine faces nested ambiguous quantifiers combined with an anchor that fails at the end of a long input:

Vulnerable Pathological Pattern

// Exponential complexity: O(2^n) const badRegex = /^(a+)+$/; badRegex.test("aaaaaaaaaaaaaaaaaaaaX");

For a 20-character string ending in a mismatch (X), the engine must explore 2^20 ≈ 1,048,576 permutations of dividing string slices between outer and inner quantifiers, blocking the main execution thread.

Deterministic Linear Refactoring

// Guaranteed linear complexity: O(n) const safeRegex = /^a+$/; safeRegex.test("aaaaaaaaaaaaaaaaaaaaX");

By flattening redundant nested quantifiers or making adjacent tokens mutually exclusive (e.g., matching non-delimiter sequences [^:\s]+ rather than arbitrary wildcards .*), the engine eliminates ambiguous branching paths.

The Statefulness Trap: lastIndex Pointer Mutation with Global (/g) Flag

One of the most frequent defects in JavaScript application logic stems from the stateful cursor mutation of RegExp instances compiled with the /g or /y flags:

The Stateful Mutation Bug

Reusing a RegExp instance compiled with the /g flag mutates its internal lastIndex pointer on each successful match:

const ID_REGEX = /^[A-Z]{3}-\d{4}$/g;

function validateId(input) {
  return ID_REGEX.test(input);
}

validateId("ABC-1234"); // true  (lastIndex mutates to 8)
validateId("ABC-1234"); // false (searches from index 8!)
validateId("ABC-1234"); // true  (resets to 0 after failure)

Because .test() resumes scanning from the end of the previous match, identical inputs alternate between passing and failing.

Defensive Engineering Solutions

Choose one of these three battle-tested strategies to guarantee idempotent evaluation:

01Omit the /g flag for boolean validation

When checking validity with .test(), avoid the g modifier entirely so lastIndex is never mutated and stays at 0.

02Explicit pointer reset before execution

If global iteration is strictly required across function scopes, explicitly reset the pointer: ID_REGEX.lastIndex = 0; before each invocation.

03Prefer String.prototype.matchAll()

Modern ECMAScript prefers str.matchAll(regex), returning an immutable iterator of matches without altering external state.

Zero-Width Lookaround Assertions: Matching Without Buffer Consumption

Lookarounds verify that text exists (or does not exist) adjacent to the current position without consuming characters or including them in the full match result ($&):

Positive Lookahead

(?=pattern)

Asserts that the subpattern matches immediately after the current position. Frequently used to validate required criteria (e.g. at least one uppercase letter) without moving the match index.

Negative Lookahead

(?!pattern)

Asserts that the subpattern does NOT match ahead. Essential for keyword exclusions (e.g. matching words not ending in .min.js) and boundary guards.

Positive Lookbehind

(?<=pattern)

Asserts that the subpattern matches immediately before the current index. Enables extracting values directly following prefixes (e.g. currency amounts after (?<=\$)\d+).

Negative Lookbehind

(?<!pattern)

Asserts that the subpattern does NOT match preceding characters. Commonly used to locate unescaped quotes or backslashes: (?<!\\)".

Cross-Engine Flavor Compatibility Matrix

When exporting patterns tested here to backend services, verify language-specific feature boundaries:

Language / RuntimeEngine ClassNamed GroupsLookaround SupportAtomic Groups / Possessive
JavaScript (ECMAScript)Traditional NFA(?<name>...)Full (variable-length lookbehind)Emulated via lookaround
Python (re module)Traditional NFA(?P<name>...)Fixed-width lookbehind onlySupported in Python 3.11+
Go (regexp package)DFA / RE2(?P<name>...)Unsupported (DFA linear restriction)Unsupported
PHP (preg_* / PCRE2)PCRE2 NFA(?<name>...) / (?P<name>...)Full (bounded variable lookbehind)(?>...) and ++, *+
Java (java.util.regex)Traditional NFA(?<name>...)Obvious maximum length lookbehind(?>...) and ++, *+

Substitution Token Architecture in Replace Mode

When executing string substitutions in the Replace panel, the replacement string interprets dollar-prefixed identifiers as runtime expansion tokens:

TokenExpansion ValuePractical Application & Example
$&Matched SubstringWraps or decorates matched targets: <mark>$&</mark> highlights words in place.
$1, $2..$99Numbered GroupReorders components: ([0-9]{4})-([0-9]{2}) replaced with $2/$1 reformats year-month pairs.
$<name>Named GroupRefactors data with semantic clarity: $<user>@internal.net swaps the domain while preserving the user variable.
$`Preceding SliceInserts the entire substring of the input located before the start index of the current match.
$'Following SliceInserts the entire substring of the input located after the end index of the current match.
$$Literal DollarEscapes the token prefix to insert a literal $ character into the output without triggering token expansion.

Frequently Asked Questions

Why does my regex match too much text (greedy vs lazy matching)?

By default, standard quantifiers (*, +, {m,n}) are greedy: they consume as many characters as possible before backtracking to satisfy the rest of the pattern. Appending a question mark makes them lazy (*?, +?, {m,n}?), matching the fewest characters necessary. For example, <.*> matches from the first < to the very last > across an entire line, whereas <.*?> halts at the first closing >.

Why does RegExp.prototype.test() alternate between returning true and false on identical inputs?

When a regular expression has the global (g) or sticky (y) flag, JavaScript makes the RegExp instance stateful by tracking its lastIndex property. Each successful .test() updates lastIndex to the end of that match. The next call searches strictly from lastIndex onwards until it fails, which resets lastIndex back to 0. For boolean validation, either omit the g flag or manually set regex.lastIndex = 0 before calling .test().

How can I prevent Catastrophic Backtracking (ReDoS) when testing complex patterns?

Catastrophic Backtracking occurs when nested or adjacent ambiguous quantifiers (such as (a+)+$ or (.*a)+) encounter a non-matching suffix, forcing the NFA engine into an exponential O(2^n) search space. To prevent this, eliminate nested quantifiers, ensure alternations do not overlap, use specific character class exclusions like [^"\n]+ instead of .*, and position anchor boundaries early.

How do I test regular expressions against multiline strings and line breaks?

Enable the Multiline (m) flag to make ^ and $ match the start and end of each individual line (\n or \r) rather than the entire string buffer. If you also need the wildcard dot (.) to match across line breaks without halting at newlines, enable the DotAll (s) flag. Both flags can be combined simultaneously as /pattern/ms.

How do named capture groups work in pattern matching and string replacement?

Enclose the subpattern in (?<groupName>...). In JavaScript match results, captured values appear on match.groups.groupName. In the Replace mode, reference the captured value using $<groupName>. Named groups keep code resilient because adding, removing, or reordering groups will never break positional numeric references ($1, $2).

What is the operational difference between positive/negative lookahead and lookbehind?

Lookarounds are zero-width assertions: they test whether adjacent text satisfies a subpattern without consuming characters or including them in the matched string ($&). Lookaheads (?=...) and (?!...) verify what follows the current index, while lookbehinds (?<=...) and (?<!...) verify what precedes it. In modern ECMAScript/V8, both fixed-width and variable-length lookbehinds are fully supported.

Why does a regular expression working in this tester fail when ported to Go (Golang)?

This tester runs on modern ECMAScript (V8), a Traditional NFA engine supporting lookaheads, lookbehinds, and backreferences. Go standard library (regexp package) uses Google RE2, a DFA-based engine that enforces guaranteed O(n) linear execution time. RE2 explicitly disallows lookaround assertions (?=...) and backreferences (\1). When porting to Go, restructure patterns using explicit delimiter boundaries or multi-step string logic.

What do the Indices (d) and Unicode (u) flags do in JavaScript?

The d (hasIndices) flag causes the engine to populate match.indices, an array containing exact start and end offset tuples for the full match and each capture group (ES2022). The u (Unicode) flag treats strings as sequences of 32-bit Unicode code points instead of 16-bit code units, enabling proper handling of emoji/astral characters and activating \p{...} property escapes.