HomeUtilitiesRegex Tester & Debugger Pro

Regex Tester & Debugger Pro

Perform advanced regular expression testing, debugging, and live analysis. Features a real-time pattern AST token explainer, a full substitution/replace engine with backreference support ($1, $2), an interactive cheat sheet quick-injector, and a library of pre-configured standard patterns (Email, URL, IP, HTML, Date). View detailed capture groups and index offsets instantly.

Perform advanced regular expression testing, debugging, and live analysis. Features a real-time pattern AST token explainer, a full substitution/replace engine with backreference support ($1, $2), an interactive cheat sheet quick-injector, and a library of pre-configured standard patterns (Email, URL, IP, HTML, Date). View detailed capture groups and index offsets instantly.

This tool is designed to provide a seamless experience for developers by handling complex operations directly in your browser with maximum speed and security.

100% Private
Instant Results
Customizable
Offline Ready
Dev-Friendly
Easy Export

A regular expression (regex or regexp) is a sequence of characters that defines a search pattern. Regex engines scan text looking for substrings that match the pattern — they can find all occurrences, check whether a string conforms to a format, split a string at pattern-defined boundaries, or replace matched substrings with new content. The power of regular expressions comes from their special characters: . matches any character, * means zero or more of the preceding element, + means one or more, ? means zero or one, ^ anchors to the start of a line, $ anchors to the end, and character classes like [a-z] match any character in a set. Combining these elements allows patterns of remarkable specificity and flexibility.

Capture groups are one of the most useful regex features. Wrapping part of a pattern in parentheses — like (\d{3})-(\d{4}) — creates a capturing group for each parenthesized section. When the pattern matches, each capture group contains the specific text that matched that portion of the pattern. In a phone number match, group 1 might capture 555 and group 2 capture 1234. Capture groups let you extract specific parts of a matched string without writing separate patterns for each part, and they are the mechanism behind named captures (?pattern), backreferences \1 that reference earlier matches, and replacement patterns $1 that insert capture group content into replacement strings.

Regex flags modify how the engine interprets the pattern. The global flag (g) finds all matches rather than stopping at the first. The case-insensitive flag (i) makes [a-z] match uppercase letters too. The multiline flag (m) makes ^ and $ match line starts and ends within the string rather than only the start and end of the entire string. The dotall flag (s) makes the dot . match newlines which it normally skips. The unicode flag (u) enables full Unicode character matching. The sticky flag (y) matches only from the lastIndex position. Getting the flags right is often the difference between a regex that works and one that matches nothing or matches too much.

Read the Full Guide

This tool applies your regular expression to your test text in real time and shows the results immediately. The Pattern field accepts any JavaScript regular expression syntax — the same engine used by JavaScript's String.prototype.match(), String.prototype.replace(), RegExp.prototype.test(), and all other JavaScript regex methods. The Flags field accepts any combination of g, i, m, s, u, and y. As you type in either field, the matches update instantly without needing to click a button. The Highlighted Matches panel shows the test text with all matches highlighted — each match is visually marked in the text so you can immediately see which substrings the pattern identifies. The match count is shown above the panel. Below the highlighted text, each individual match is listed with its match index (position in the string where the match starts) and the content of each capture group within that match. If your pattern has two capture groups, each match row shows both group values with their group numbers, making it immediately clear what each parenthesized section of your pattern is extracting. The Copy Matches button copies all match results to your clipboard as a clean list — useful when you want to paste the extracted values into another tool, documentation, or a test file. The tool uses JavaScript's native RegExp engine, which means the results match exactly what you would see running the same pattern in a browser console or in Node.js. There are no dialect differences or subtle compatibility issues — what you test here is what you get in production JavaScript code.

1. Enter your regular expression pattern in the Pattern field — type the regex between the two forward slash delimiters / pattern /. The pattern uses JavaScript regex syntax: use . for any character, \d for digits, \w for word characters, \s for whitespace, + for one or more, * for zero or more, ? for optional, {n} for exactly n repetitions, ^ for start anchor, $ for end anchor, and parentheses () for capture groups.

2. Click Load Example to see a working pattern with test text before writing your own.

Set the flags in the Flags field — type any combination of g (global, find all matches), i (case-insensitive), m (multiline, ^ and $ match line boundaries), s (dotall, dot matches newlines), u (unicode mode), y (sticky). The most commonly needed flags are g to find all occurrences rather than stopping at the first match, and i to match regardless of case. Leave the flags field empty to find only the first match in a case-sensitive search.

3. Enter the test text in the Test String field — paste or type any text you want to test the pattern against. Use realistic examples: if your pattern is meant to extract phone numbers from user input, paste several different phone number formats. If it is for log parsing, paste actual log lines. The more representative your test text, the more confident you can be that the pattern works correctly.

4. Read the Highlighted Matches panel — all matches are highlighted in the test text, and the match count is shown. Below the highlights, each individual match is listed with its starting index position and the value of each capture group. Check that every match is correct, that no matches are spurious (matching text they should not match), and that the capture group values contain the data you expect to extract.

5. Refine the pattern based on what you see — if matches are too greedy (consuming too much text), make the quantifiers non-greedy by adding ? after them (* becomes *?, + becomes +?). If matches are missing, check your character classes and anchors. If capture groups contain the wrong text, adjust the group boundaries. Copy the final working pattern from the Pattern field for use in your JavaScript code: new RegExp(pattern, flags) or the literal /pattern/flags syntax.

Regular expressions are simultaneously one of the most powerful tools in a developer's toolbox and one of the most opaque. A regex that works perfectly on the test cases you thought of can fail silently on edge cases you did not consider: the phone number pattern that does not handle international formats, the email validator that rejects technically valid addresses, the URL extractor that matches too greedily and captures trailing punctuation, the log parser that works on production logs but breaks on logs from a different server that uses a slightly different format. The only way to build confidence that a regex is correct is to test it against a variety of real inputs and see exactly what it matches and what it misses. That is what this tool is for. The visual match highlighting is what makes a regex tester genuinely useful rather than just a convenience. When a regex is not working, the problem is almost never obvious from reading the pattern — you cannot mentally simulate the backtracking behavior of a complex pattern with lookaheads and nested groups. But when you can see the highlights on the actual text and see which capture groups are populated with which values, the problem becomes visible immediately. Is the match starting one character too early? Is the greedy quantifier consuming too much? Is the wrong alternative branch of an alternation being taken? These questions are answered by looking at the highlighted output, not by staring at the pattern. The capture group display also serves a documentation function. When you are writing a regex to extract specific fields from a log line, an API error message, or a structured text format, each capture group is a named piece of information you are extracting. Seeing each group value listed separately for each match tells you immediately whether you have the groups in the right order, whether a group is capturing the right text, and whether you need to add or remove groups to get the extraction structure you need for the downstream code that will use the matches.

Real-time matching — matches update instantly as you type in the pattern or test text field with no button click required making the iteration loop fast

Visual match highlighting — all matches are highlighted in the test text so you can immediately see which substrings the pattern identifies and whether any spurious or missed matches are visible

Capture group display — each match shows the value of every capture group by number so you can verify exactly what each parenthesized section of the pattern is extracting

All JavaScript flags supported — g i m s u and y flags are all supported matching the complete JavaScript regex flag set so what you test is what you get in production JavaScript

Copy Matches button — copies all match results as a clean list for use in documentation tests or downstream processing

JavaScript engine fidelity — uses the native browser JavaScript regex engine so results exactly match what your application code produces with no dialect differences

100% browser-based — your test patterns and test text including sensitive data and proprietary pattern logic never leave your machine

Supports large test text — paste entire log files API responses or any other large text bodies to test your pattern against real-world input volume

Testing input validation patterns for forms (email addresses & phone numbers & postal codes & passwords) before adding them to application code

Debugging log parsing regexes by testing against real log lines to verify field extraction

Extracting specific values from structured text like API error messages & file paths or version strings

Building and testing URL parsing patterns to extract protocol & hostname & path and query parameters

Writing and verifying search-and-replace patterns for code refactoring or text transformation

Testing patterns for CSV or delimiter-separated value parsing to handle quoted fields correctly

Debugging capture group extraction patterns to verify each group captures the intended text

Learning regex syntax by experimenting with patterns and seeing immediate visual feedback on what they match

Example Input

Pattern: (\d{3})-(\d{3})-(\d{4})
Flags: g
Test text: My phone number is 123-456-7890. Call me at 987-654-3210.

Example Output

Highlighted matches (2): "123-456-7890" and "987-654-3210" highlighted in the test text

Match #1: "123-456-7890" (index 19)
  Group 1: "123"
  Group 2: "456"
  Group 3: "7890"

Match #2: "987-654-3210" (index 42)
  Group 1: "987"
  Group 2: "654"
  Group 3: "3210"

Invalid Regex Syntax: If the pattern field shows a red error indicator, the regex has a syntax error that prevents it from being compiled. Common syntax errors include unmatched parentheses (an opening ( without a closing )), unescaped special characters (using . * + ? ^ $ { } [ ] | ( ) \\ without escaping them when you want the literal character), and invalid character class syntax (like [z-a] where the range is backwards). Fix the syntax error shown in the error message before the pattern can be applied to the test text.

No Matches Found: If the pattern is valid but shows zero matches, the pattern does not match anything in the test text. Common causes: the pattern is more specific than you realized (like ^\\d+$ requires the entire string to be digits, not just contain digits), the case-sensitive flag is on and the text has different casing than the pattern, or the multiline flag (m) is off and ^ / $ match only the document start and end rather than line boundaries. Add the g flag to find all matches if you only got the first one. Add the i flag if case differences might be the issue.

Infinite Loops From Catastrophic Backtracking: Some regex patterns that combine multiple quantifiers on overlapping character classes — like (a+)+ or (x*|y*)* — can cause catastrophic backtracking where the regex engine tries an exponentially large number of matching paths for non-matching input. This causes the browser tab to freeze or become unresponsive. If the tool appears to hang after entering a pattern, it is likely a catastrophically backtracking pattern. Open browser DevTools, go to the console, and stop execution. Then simplify the pattern by removing nested quantifiers. This is also called ReDoS (Regular Expression Denial of Service) and is a real security vulnerability in production applications.

Greedy Matching Consuming More Text Than Intended: Quantifiers like .* and .+ are greedy by default — they match as much text as possible. A pattern like <.*> intended to match a single HTML tag like <div> on a line that contains <div>Hello</div> will match the entire <div>Hello</div> because .* greedily consumes everything up to the last >. Make the quantifier non-greedy by adding ? after it: <.*?> matches only <div> and </div> separately. Non-greedy quantifiers match as little as possible rather than as much as possible.

Anchors Not Working As Expected With Multiline Text: The ^ and $ anchors have different behavior depending on the multiline flag. Without the m flag, ^ matches only the very start of the entire test string and $ matches only the very end. With the m flag (multiline), ^ matches the start of each line and $ matches the end of each line. If your pattern is supposed to match at the beginning of each line but is only matching at the start of the entire string, add the m flag. Similarly, if you want to match the exact entire string with no surrounding text, use ^ at the start and $ at the end without the m flag.

Not using the global flag (g) and only getting the first match

Fix: By default, a regex finds the first match in a string and stops. This is correct behavior for test() and the first use of exec() but can be surprising when using match() or replace() — without the g flag, match() returns only the first match and replace() replaces only the first occurrence. Add the g flag to your pattern to find all matches. In this tester, without the g flag you will see at most one highlighted match even if the test text contains multiple occurrences. For production JavaScript code: /pattern/g for global matching or new RegExp(pattern, 'g').

Writing a regex that works on test data but fails on real-world input edge cases

Fix: A regex that matches your test cases is not necessarily a correct regex. The test cases you think of when writing the pattern are the obvious ones — the regex needs to handle the edge cases you did not think of. For input validation patterns (email, phone, URL), test with: valid inputs that are unusual but correct (email addresses with + signs, phone numbers with country codes, URLs with ports and query strings), invalid inputs that look similar (addresses missing the @ or with double @, phone numbers with letters), and boundary cases (empty string, very long input, input with only special characters). If you are using the regex to process data you do not control — user input or third-party API responses — test with as many variations as you can find.

Using dot (.) to match any character when you mean to match a literal period

Fix: In regex, the dot . is a special character that matches any character except a newline (and newlines too with the s flag). If you want to match a literal period, you must escape it: \. So the pattern for an IP address like 192\.168\.1\.1 requires escaped dots to match the literal periods between the octets. Using 192.168.1.1 without escaping matches 192X168Y1Z1 where X, Y, Z are any characters — it would match 192a168b1c1 which is not a valid IP address. This is one of the most common regex mistakes: using unescaped . when a literal period is intended. The same applies to other special characters: \* for a literal asterisk, \+ for a literal plus, \? for a literal question mark, \( and \) for literal parentheses.

Using regex for HTML parsing instead of a proper HTML parser

Fix: Regular expressions cannot reliably parse HTML because HTML is not a regular language — it has recursive nesting (elements inside elements) that regex cannot handle correctly. A regex that seems to work for simple cases like extracting all attributes will break on HTML with nested quotes, multi-line attributes, comments, CDATA sections, or malformed HTML that a browser would render correctly but that your regex cannot predict. For parsing HTML in JavaScript, use DOMParser or document.querySelectorAll. In Node.js, use cheerio or jsdom. For extracting data from HTML pages, use a proper DOM traversal library. Reserve regex for well-defined structured text formats, not HTML or XML.

Not anchoring the pattern when validating an entire string

Fix: If you want to validate that an entire string matches a pattern — for example that a field contains only digits — you must anchor the pattern with ^ at the start and $ at the end. Without anchors, \d+ matches any string that contains at least one digit anywhere — it would match abc123xyz because 123 matches \d+. With anchors, ^\d+$ matches only strings that consist entirely of digits with nothing before or after. Unanchored validation patterns are a common security mistake in input validation — a pattern that is supposed to reject non-numeric input silently accepts strings that contain numbers plus other characters.

Does it support all regex features?

Yes. The tester uses the browser's native JavaScript RegExp engine and supports the complete JavaScript regular expression syntax: character classes, quantifiers, anchors, groups (capturing, non-capturing, named), backreferences, lookaheads (positive and negative), lookbehinds (positive and negative), and all six flags (g, i, m, s, u, y). Since it uses the actual JavaScript engine, the results exactly match what your production JavaScript code will produce — there are no compatibility differences or missing features.

Can I test multiple strings at once?

Yes. Paste a large body of text containing multiple potential matches and the tool with the g (global) flag will find and highlight all of them simultaneously. The Highlighted Matches count shows how many total matches were found and each match is listed separately below with its index position and capture group values. For testing multiple completely different strings as separate test cases, test them one at a time by replacing the test string between tests, or put all your test cases in one block with clear separators between them.

Is it safe for sensitive test data?

Yes. All regex processing runs entirely in your browser using the native JavaScript RegExp engine. Your test patterns and test text — including patterns that reveal your application's validation logic, and test text that may contain real user data, log entries with personal information, or security-sensitive strings — never leave your machine and are never transmitted to any server. This is important for engineers who need to test regex against real data samples that contain PII or operational security information.

What are named capture groups and how do I use them?

Named capture groups use the syntax (?pattern) to assign a name to a capture group instead of just a number. A pattern like (?\d{4})-(?\d{2})-(?\d{2}) creates three named groups — year, month, day — that are accessible by name rather than index. In JavaScript, named groups appear in the match result's groups property: match.groups.year, match.groups.month, match.groups.day. Named groups make regex patterns more readable and maintenance easier because the group index does not need to be tracked — adding a group before an existing one does not break all the downstream code that references subsequent groups by number.

What is the difference between greedy and non-greedy quantifiers?

Greedy quantifiers (*, +, {n,m}) match as much text as possible. Non-greedy quantifiers (*?, +?, {n,m}?) match as little as possible. Given the text bold and the pattern <.*>, the greedy version matches the entire bold because .* consumes everything up to the last >. The non-greedy version <.*?> matches only and then as separate matches. Use non-greedy quantifiers when you want to match the shortest possible string between delimiters. The default greedy behavior is usually what you want for most patterns, but HTML and JSON parsing often requires non-greedy matching to avoid consuming too much.

What is a lookahead and when do I use it?

A lookahead is a zero-width assertion that matches a position in the string based on what follows it, without consuming the following characters. A positive lookahead (?=text) matches a position only if text follows at that position. A negative lookahead (?!text) matches a position only if text does not follow. For example, \d+(?= dollars) matches a number that is followed by the word dollars but does not include dollars in the match. Lookaheads are useful when you want to match something based on its context without including the context in the match result. Lookbehinds (?<=text) work similarly but look at what precedes the position rather than what follows.

What is ReDoS and should I worry about it?

ReDoS (Regular Expression Denial of Service) is a vulnerability where a carefully crafted input causes a regex engine to take exponential time to determine that the input does not match, effectively freezing the application. It occurs in patterns with nested quantifiers on overlapping character classes — patterns like (a+)+ or (x|xx)+ where the engine must try an exponentially large number of paths on backtracking inputs. In a browser this freezes the tab. In a Node.js server this blocks the event loop. To prevent ReDoS: avoid nested quantifiers, use atomic groups or possessive quantifiers where supported, set timeouts on regex operations, and test your patterns against long non-matching inputs to see if they hang. This tester may freeze on a catastrophically backtracking pattern — the browser may ask if you want to stop the script.

How do I use the regex from this tester in my JavaScript code?

Once you have a working pattern and flags in the tester, copy the pattern text and use it in JavaScript in one of two ways. Regex literal syntax: const pattern = /your-pattern/flags — for example const emailPattern = /[\w.]+@[\w.]+\.\w+/g. Constructor syntax: const pattern = new RegExp('your-pattern', 'flags') — for example new RegExp('[\\w.]+@[\\w.]+\\.\\w+', 'g'). Note that backslashes must be doubled in constructor strings (\d becomes \\d) because the string parser consumes one backslash before the regex engine sees it. The literal syntax is usually cleaner. Use the pattern with str.match(pattern), str.replace(pattern, replacement), pattern.test(str), or pattern.exec(str) depending on what you need to do with the matches.