Live regular expression tester with match highlighting and capture group display. Uses the JavaScript RegExp engine. Matches update as you type.
This regex tester uses the JavaScript RegExp engine to test regular expressions with live match highlighting. Enter a pattern, select flags, and type your test string β matches are highlighted inline and detailed in the Match Details panel. Use the Pattern Library to load 12 pre-built patterns for common engineering use cases.
g (global): Find all matches in the string, not just the first. Without g, the regex stops after the first match. Almost always use g when searching for multiple occurrences. i (insensitive): Case-insensitive matching β [a-z] also matches A-Z and vice versa. Useful for matching email domains, commands, or any user-facing text. m (multiline): ^ and $ match the start and end of each LINE rather than the entire string. Required when searching for line-start patterns in multi-line text. s (dotAll): The . metacharacter matches any character including newlines (\n). By default, . does not match \n. Use s when your pattern needs to match content that spans multiple lines.
Parentheses () create a capture group β the text matched by the group is available as a separate result. For example, (\d{4})-(\d{2})-(\d{2}) matching "2026-06-24" produces Group 1: 2026, Group 2: 06, Group 3: 24. Capture groups are used in JavaScript's String.replace() to reference parts of the match: "2026-06-24".replace(/(\d{4})-(\d{2})-(\d{2})/, "$2/$3/$1") β "06/24/2026". Named capture groups use (?<name>pattern) syntax β accessible as match.groups.name in JavaScript. Non-capturing groups (?:pattern) group without capturing β useful for alternation without capturing: (?:https?|ftp):// matches the protocol without creating a group for it.
Lookahead (?=pattern): matches a position where the next characters match pattern, without consuming them. Example: \w+(?=\s+dollars) matches the word before " dollars" β "fifty" in "fifty dollars". Negative lookahead (?!pattern): matches a position where the next characters do NOT match pattern. Lookbehind (?<=pattern): matches a position preceded by pattern. Example: (?<=\$)\d+ matches digits preceded by a dollar sign. Negative lookbehind (?<!pattern): matches a position NOT preceded by pattern. Lookaheads and lookbehinds are zero-width β they assert a condition without consuming characters, so the full match doesn't include the lookahead content.
Catastrophic backtracking occurs when a regex with nested quantifiers on overlapping patterns encounters a non-matching string, causing the engine to explore exponentially many paths before failing. The classic example is (a+)+ on "aaaaaaaaab" β the outer and inner quantifiers both match "a", so the engine tries every combination of how to split the as between the two quantifiers. Avoid: nested quantifiers on similar character classes (e.g., (\w+\s)+), alternation between patterns that can both match the same text without backtracking guards. Fix with: atomic groups (not in JavaScript), possessive quantifiers (not in JavaScript), or by restructuring the regex to eliminate ambiguity. In JavaScript, prefer specific character classes over .* when possible.
This tester uses the JavaScript (ECMAScript) RegExp engine β the same engine used in Node.js, Chrome V8, and Firefox SpiderMonkey. JavaScript regex supports most standard PCRE features: character classes, quantifiers, alternation, capture groups, named groups, lookahead/lookbehind, and Unicode mode (u flag). It does NOT support some Perl/PCRE features: atomic groups, possessive quantifiers, conditional patterns, recursive patterns, or full Unicode category support. If you're writing regex for Python (re/regex), Java, or Go, most patterns work the same β but lookbehind support and some advanced features differ.
Escape it with a backslash. In JavaScript regex, special characters that need escaping are: . ^ $ * + ? { } [ ] \ | ( ). For example, to match a literal dot in an IP address, use \. β without the escape, . matches any character. To match a literal backslash, use \\. When entering a pattern in this tester, you type the pattern as it would appear in a /pattern/ regex literal, not as a JavaScript string β so you type \. not \\. (which you'd use in a string-quoted regex like new RegExp("\\.")).
Too much (greedy): quantifiers like * and + are greedy by default β they match as much as possible. Use lazy quantifiers *? and +? to match as little as possible. For example, <.+> on "<b>bold</b>" matches the entire string. <.+?> matches "<b>" only. Too little: your character class or quantifier may be too restrictive. Check that you're matching the right character class (\w matches [a-zA-Z0-9_] β doesn't match hyphens or accented characters). Too anchored: ^ and $ anchors with the m flag match line boundaries; without m, they match the entire string boundary.
Yes β paste multiline text into the test string field. For patterns that should match across line boundaries, enable the s (dotAll) flag so . matches newlines. For patterns where ^ and $ should match each line boundary (not just the start/end of the full string), enable the m (multiline) flag. Example: with the m flag, ^\s*// matches any line starting with optional whitespace then //, useful for detecting comment lines in code.
Use a regex literal: const re = /your-pattern/flags; or the RegExp constructor: const re = new RegExp("your-pattern", "flags"). For finding all matches: const matches = text.match(/pattern/g) β returns array of matched strings, or null. For detailed match info including capture groups: use re.exec(text) in a loop (with g flag) or text.matchAll(/pattern/g) (returns iterator of match arrays). For test (boolean): re.test(text). For replace: text.replace(/pattern/g, replacement) β use $1, $2 to reference capture groups in replacement.