Online Regex Tester & Debugger

Test and debug regex online with live match highlighting, capture-group details, plain-English explanations, and 90+ ready patterns. Free, in your browser.

Advertisement

Free Online Regex Tester & Debugger

This regex tester runs your pattern against your test string as you type and shows you exactly what matched, where it matched, and what each capture group caught. Type a pattern in the top box, paste sample text underneath, and every match is highlighted in place while a details panel lists the character offsets and group contents. Nothing is uploaded — the matching happens in your browser using the JavaScript regular expression engine, so your log lines, customer records, and config snippets never leave your machine.

It is built for the two situations where people actually reach for a regex tester: writing a new pattern from scratch and needing fast feedback, and debugging someone else’s pattern that almost works. For the first case there is a library of roughly ninety ready-made patterns across eighteen categories — email, URL, phone, date, IP, payment, password, HTML, colour, files, path, crypto, security, social, markdown, numbers, text, and code — that you can load with one click and then edit. For the second, a live explanation panel breaks the pattern into plain-English components so you can see what a wall of brackets and backslashes is actually asking for.

What the Regex Tester Shows You

  • Live match highlighting — the test string is re-scanned about a third of a second after you stop typing, with every match highlighted inline and a running match count above the box.
  • Match details — each match is listed with its start and end offsets and the literal text that matched, followed by every capture group as $1, $2, and so on with their own positions. This is the panel that tells you whether your groups are capturing what you think they are.
  • Pattern explanation — a breakdown of the constructs present in your pattern (anchors, character classes, quantifiers, groups, lookahead, alternation) in readable sentences.
  • Flag toggles — all six JavaScript flags: g global, i case-insensitive, m multiline, s dotAll, u unicode, and y sticky. The flag row next to the pattern box lights up to show which are active.
  • Syntax validation — an invalid pattern shows the engine’s own error message (unterminated group, invalid quantifier, bad escape) instead of silently returning nothing.
  • Pattern library and quick presets — six one-click presets (email, IPv4, phone, URL, US date, hex colour) that load a pattern and matching sample text, plus the full searchable library filtered by category.
  • Shareable link — the pattern, test string, and flag settings are encoded into the URL, so you can paste a working example straight into a code review or a ticket.
  • Quick reference — a collapsible cheat sheet of character classes, quantifiers, anchors, groups, lookaround, and escapes.

How to Use It

  1. Load a starting point. Click a preset or pick something from the pattern library if a similar pattern already exists. Starting from a working email or IPv4 pattern is almost always faster than starting from an empty box.
  2. Paste real test data. Use actual lines from your log, CSV, or config — including the awkward ones. Patterns that pass on hand-written examples routinely fail on real data because of trailing whitespace, unexpected Unicode, or blank lines.
  3. Set your flags. Global is on by default so you see every match rather than only the first. Turn on m if you want ^ and $ to anchor to each line, and s if you need . to cross newlines.
  4. Read the match details, not just the highlighting. Highlighting tells you something matched; the offsets and capture groups tell you whether it matched the right thing. A group showing an empty string is the usual sign of a misplaced quantifier.
  5. Tighten, do not loosen. When a pattern over-matches, the fix is almost always a narrower character class or an anchor — not another .*.
  6. Share the link. Copy the shareable URL so the next person sees the exact pattern, sample, and flags you were looking at.

Character Classes and Quantifiers

A character class defines a set of characters that a single position may match. [a-z] matches one lowercase letter; [^0-9] matches one character that is not a digit; [A-Fa-f0-9] matches one hex digit. The shorthand classes are \d (digit), \w (word character: letters, digits, underscore), and \s (whitespace), each with an inverted uppercase form — \D, \W, \S. Inside square brackets most metacharacters lose their special meaning, which is why [.+*] matches a literal dot, plus, or asterisk with no escaping. The exceptions are ^ at the start (negation), - between characters (range), and ] and \ themselves.

Quantifiers say how many times the preceding element may repeat: * is zero or more, + is one or more, ? is zero or one, and {3}, {3,}, {3,5} give exact, minimum, and bounded counts. The single most common bug in hand-written regex is applying a quantifier to the wrong element. \d{3}-\d{4} matches three digits, a hyphen, then four digits. (\d-){3} matches “digit hyphen” three times — a very different thing. Group first, then quantify.

Greedy vs Lazy: The Classic HTML Trap

By default quantifiers are greedy: they consume as much as possible and then give characters back only if the rest of the pattern fails. Adding ? after a quantifier makes it lazy, consuming as little as possible and expanding only when forced.

Test string: <b>bold</b> and <i>italic</i>

  • <.+> produces one match: the entire string from the first < to the last >. The greedy .+ ran to the end of the line and only backtracked far enough to find a final >.
  • <.+?> produces four matches: <b>, </b>, <i>, </i>. The lazy quantifier stops at the first > it can.
  • <[^>]+> also produces four matches and is the version to prefer — a negated character class cannot overshoot, so there is no backtracking to undo.

That last point matters beyond tidiness. Nested greedy quantifiers over overlapping character sets — the classic shape being (a+)+$ or (\s*\w+)*$ — can make the engine explore an exponential number of paths on input that nearly matches. That is catastrophic backtracking, and when the pattern is applied to user-supplied input it becomes a denial-of-service bug (ReDoS). Paste a long non-matching string into the test box and watch for the page stalling; if a pattern takes noticeably long on a few hundred characters, rewrite it with negated classes and possessive-style anchoring rather than shipping it.

Capture Groups, Non-Capturing Groups, and Backreferences

Parentheses do two jobs at once: they group elements so a quantifier or alternation applies to the whole unit, and they capture the matched text for later use. When you only want the grouping, use (?:…). It keeps the numbering of your real groups stable and avoids storing text you will never read.

Worked example on the test string 2026-08-12:

  • (\d{4})-(\d{2})-(\d{2}) — one match, three groups: $1 = 2026, $2 = 08, $3 = 12.
  • (?:\d{4})-(\d{2})-(\d{2}) — same match, but now $1 = 08 and $2 = 12; the year is grouped but not captured.
  • (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) — named groups, readable in replacement strings as $<year> and far easier to maintain than positional numbers when the pattern grows.

A backreference matches whatever a previous group actually captured, not the pattern that captured it. (["'])(.*?)\1 matches a quoted string and guarantees the closing quote is the same character as the opening one — something no character class can express. Similarly \b(\w+)\s+\1\b finds doubled words like “the the” in prose.

Lookahead and Lookbehind

Lookaround assertions test whether something is present at a position without consuming any characters, so the text they inspect never appears in the match. There are four forms: positive lookahead (?=…), negative lookahead (?!…), positive lookbehind (?<=…), and negative lookbehind (?<!…).

The everyday use is a password rule that has to check several independent conditions on the same string. ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{12,}$ reads as: from the start, assert somewhere ahead there is a lowercase letter, and separately an uppercase letter, and separately a digit, and separately a symbol — then actually consume at least twelve characters to the end. Each lookahead starts over from position zero, which is why order does not matter and why you cannot express this with a single linear pattern.

Lookbehind is how you match a value while excluding its label: (?<=Authorization:\s)\S+ captures the token without the header name, so the match itself is clean enough to feed straight into a script. Negative lookahead is how you exclude exceptions: ^(?!.*(?:test|staging)\.)[\w.-]+\.example\.com$ matches your production hostnames but not the test ones.

Flavour Differences: JavaScript, PCRE, and Python

This tester runs the JavaScript engine — the same engine your browser and Node.js use — so what you see here is exactly what String.prototype.match and RegExp.exec will do. Most patterns transfer to other languages unchanged, but a handful of differences bite regularly:

  • Named groups. JavaScript and PCRE use (?<name>…). Python accepts (?P<name>…) as well as the modern form, and older Python code you inherit will use the ?P spelling.
  • Lookbehind. JavaScript and PCRE2 support variable-length lookbehind. Python’s re module requires fixed-width lookbehind, so (?<=\s+) is a compile error there — you need the third-party regex module or a restructured pattern.
  • Dot and newline. JavaScript uses the s flag; Python uses re.DOTALL; PCRE uses (?s) inline. Same behaviour, three spellings.
  • Anchors. In Python $ also matches just before a trailing newline, and \Z is the strict end-of-string anchor. JavaScript has no \Z.
  • Unicode. JavaScript needs the u flag before \p{L} and friends work; in Python 3 \w is Unicode-aware by default; in PCRE you generally need the UTF and UCP options.
  • Atomic groups and possessive quantifiers. (?>…) and a++ exist in PCRE and Java and are the cleanest defence against catastrophic backtracking. JavaScript has neither, so in JS you prevent backtracking by writing narrower character classes instead.
  • Go. Go’s regexp package uses RE2, which has linear-time guarantees but deliberately omits backreferences and lookaround entirely. A pattern that relies on (?=…) will not compile there, no matter how correct it is.

The practical rule: prototype here, then check the two or three constructs above against your target language before shipping.

Frequently Asked Questions

Is this regex tester free, and does my data get uploaded?

It is free with no signup, and nothing is uploaded. Pattern matching runs entirely in your browser, so you can safely paste production log lines or records that you would not want to send to a third-party server.

Which regex flavour does the tester use?

The JavaScript engine built into your browser, with all six standard flags available. Patterns using only common constructs behave identically in PCRE and Python; see the flavour section above for the specific cases that differ.

Why does my pattern match the whole line instead of one field?

Almost certainly a greedy quantifier. Replace .* with a lazy .*? or, better, with a negated character class such as [^,]* or [^>]* that physically cannot cross the delimiter.

What is the difference between (abc) and (?:abc)?

Both group the enclosed elements so quantifiers and alternation apply to the whole unit. Only the first captures the matched text into a numbered group. Use the non-capturing form when you are grouping for structure, so your group numbers stay meaningful.

Why does my lookbehind work here but fail in Python?

Python’s standard re module only allows fixed-width lookbehind. A lookbehind containing +, *, or an alternation of different lengths compiles fine in JavaScript and PCRE2 but raises an error in Python. Either fix the width or use the regex package.

What does the m flag actually change?

With multiline off, ^ and $ anchor to the start and end of the whole string. With it on, they anchor to the start and end of every line. It has no effect on . — that is the s flag.

Why does the tester freeze on a long test string?

That is catastrophic backtracking, and it is a finding rather than a bug. Nested quantifiers over overlapping sets, such as (\w+\s?)+$, force the engine down exponentially many paths on near-matching input. If it stalls here it will stall in production too — rewrite it before shipping.

How do I match an exact whole word rather than a substring?

Wrap it in word boundaries: \bcat\b matches “cat” but not “concatenate”. A word boundary is a zero-width position between a \w and a non-\w character, so it consumes nothing and does not appear in the match.

Can I validate email addresses with a regex?

Only roughly. The library’s simple and RFC 5322 email patterns catch typos and malformed input, which is the honest limit of syntax checking — a syntactically perfect address may still have no mail server behind it. To check whether a domain can actually receive mail, use the Email Validator & MX Checker.

How do I share a pattern with a colleague?

Use the share button. The pattern, test string, and active flags are encoded into the URL, so the link reproduces exactly the state you were looking at.

Related Tools

Once a pattern is producing the right matches, the next step is usually the data itself. Use the JSON Validator & Formatter to check structured output, the YAML to JSON Converter when the extracted values are headed into a config file, and the Dockerfile Generator when the script that runs your pattern needs somewhere to live.

What Is Regular Expression Testing

A regular expression (regex) tester allows you to write, test, and debug regex patterns against sample text in real time. Regular expressions are a powerful pattern-matching language used across virtually all programming languages, text editors, command-line tools, and databases. They match strings based on patterns rather than literal values—enabling search, validation, extraction, and replacement operations that would be impractical with simple string methods.

Despite their power, regular expressions have a notoriously steep learning curve. A single misplaced quantifier or forgotten escape character can cause a pattern to match nothing, match too much, or run catastrophically slowly. A regex tester provides instant visual feedback—highlighting matches, showing capture groups, and explaining pattern behavior—transforming regex development from trial-and-error into an interactive process.

How Regular Expressions Work

Regular expressions define patterns using a combination of literal characters and metacharacters:

MetacharacterMeaningExampleMatches
.Any character (except newline)a.cabc, a1c, a-c
*Zero or more of precedingab*cac, abc, abbc
+One or more of precedingab+cabc, abbc (not ac)
?Zero or one of precedingcolou?rcolor, colour
\dAny digit [0-9]\d{3}123, 456
\wWord character [a-zA-Z0-9_]\w+hello, var_1
\sWhitespace\s+spaces, tabs, newlines
^Start of string/line^HelloHello at line start
$End of string/lineworld$world at line end
[abc]Character class[aeiou]Any vowel
(group)Capture group(\d{4})Captures 4 digits
(?:group)Non-capturing group(?:https?)://Matches but doesn't capture
|Alternation (OR)cat|dogcat or dog

Common regex patterns:

Use CasePatternMatches
Email (basic)[\w.+-]+@[\w-]+.[\w.]+user@example.com
IPv4 address\d{1,3}(.\d{1,3}){3}192.168.1.1
Date (ISO)\d{4}-\d{2}-\d{2}2024-01-15
URLhttps?://\S+https://example.com/path
Phone (US)(?\d{3})?[-.\s]?\d{3}[-.\s]?\d{4}(512) 555-0100

Common Use Cases

  • Input validation: Verify that form fields match expected formats (email, phone, postal code)
  • Log parsing: Extract timestamps, IP addresses, and error codes from log files
  • Data extraction: Pull structured data from unstructured text (scraping, ETL)
  • Search and replace: Transform text patterns across files (rename variables, reformat dates)
  • Security: Write detection rules for IDS/IPS, SIEM, and WAF systems

Best Practices

  1. Test with both matching and non-matching inputs — A regex that matches everything you want might also match things you don't
  2. Use non-greedy quantifiers when appropriate.*? instead of .* prevents over-matching in patterns with multiple delimiters
  3. Anchor patterns when validating — Use ^ and $ to ensure the entire string matches, not just a substring
  4. Avoid catastrophic backtracking — Nested quantifiers like (a+)+ can cause exponential processing time; use atomic groups or possessive quantifiers
  5. Comment complex patterns — Use the verbose/extended flag (x) to add whitespace and comments to long regex patterns

Frequently Asked Questions

What is a regular expression (regex) and when should I use it?+

Regular expression (regex) is a pattern-matching language for searching and manipulating text. Uses special characters like . (any character), * (zero or more), + (one or more), ? (optional), [] (character class), () (group). Common uses: validate email/phone formats, extract data from logs, find/replace in code editors, parse URLs, sanitize user input, search documents, split strings. Example: /\d{3}-\d{2}-\d{4}/ matches SSN format 123-45-6789. More powerful than simple string search but harder to read. Use for complex patterns; use indexOf() for simple exact matches. This tool tests patterns with live highlighting.

What are the most common regex patterns I should know?+

Email: /^[a-zA-Z0-9.%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/. URL: /https?://(www.)?[-a-zA-Z0-9@:%.+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b/. Phone (US): /^(?\d{3})?[-.\s]?\d{3}[-.\s]?\d{4}$/. Date (YYYY-MM-DD): /^\d{4}-\d{2}-\d{2}$/. IP address: /^(\d{1,3}.){3}\d{1,3}$/. Hex color: /^#?([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})$/. Username (alphanumeric): /^[a-zA-Z0-9_]{3,16}$/. Password (min 8, 1 upper, 1 lower, 1 digit): /^(?=.[a-z])(?=.[A-Z])(?=.*\d).{8,}$/. This tool includes common patterns library for quick testing.

What are regex flags and when should I use them?+

Flags modify regex behavior, added after closing delimiter (/pattern/flags). Common flags: g (global) - find all matches, not just first. i (ignore case) - case-insensitive matching (A = a). m (multiline) - ^ and $ match line breaks, not just string start/end. s (dotall) - . matches newlines. u (unicode) - proper unicode character handling. y (sticky) - match at exact position. Example: /test/gi finds all "test", "TEST", "Test" occurrences. Without g, stops after first match. Use g for find-all, i for case-insensitive, m for multi-line text. This tool supports all major flags with real-time preview.

How do I use capture groups and backreferences in regex?+

Parentheses () create capture groups to extract matched portions. Example: /(\d{3})-(\d{3})-(\d{4})/ in "555-123-4567" captures "555", "123", "4567" as groups 1, 2, 3. Backreferences reuse captured groups: \1, \2 refer to first, second group. Example: /(\w+)\s\1/ matches repeated words ("the the"). Named groups: /(?\d{3})-(?\d{3})/ creates named captures. Non-capturing groups: /(?:abc)+/ groups without capturing (faster). Use cases: swap date formats, find duplicate words, extract structured data. JavaScript: match()[1], replace("$1-$2"). This tool highlights capture groups and shows extracted values.

What is the difference between greedy and lazy quantifiers?+

Quantifiers (* + {n,m}) are greedy by default - match as much as possible. Example: /<.>/ on "text" matches entire string (greedy). Lazy (non-greedy) quantifiers add ? after quantifier - match as little as possible. Example: /<.?>/ matches "", then "" separately. Greedy: .* (zero or more, greedy), .+ (one or more, greedy), .{2,5} (2-5, greedy). Lazy: .*? .+? .{2,5}?. Use lazy for: HTML tag extraction, avoiding over-matching, parsing nested structures. Use greedy for: full line matching, whole word extraction. This tool shows greedy vs lazy behavior with match highlighting.

How do I validate email addresses with regex?+

Basic email regex: /^[^\s@]+@[^\s@]+.[^\s@]+$/ (allows most valid emails). Comprehensive: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$/ (stricter). Validation challenges: RFC 5322 spec is complex (allows quoted strings, comments), international domains (unicode characters), new TLDs (.museum, .technology), plus addressing (user+tag@domain.com). Best practice: use simple regex for UI validation, send confirmation email for real verification. Don't over-restrict (user@domain.co is valid). This tool tests email patterns against real examples and highlights match groups for debugging custom patterns.

What are lookaheads and lookbehinds (regex assertions)?+

Assertions match position, not characters. Positive lookahead (?=pattern) - matches if followed by pattern. Example: /\d(?= dollars)/ matches "5" in "5 dollars" but not "5 euros". Negative lookahead (?!pattern) - matches if NOT followed by pattern. Positive lookbehind (?<=pattern) - matches if preceded by pattern. Example: /(?<=$)\d+/ matches "100" in "$100". Negative lookbehind (?<!pattern). Use cases: password validation (must contain uppercase: (?=.*[A-Z])), extract values after labels, match words except in quotes. Browser support: lookbehind added in ES2018. This tool tests all assertion types with position highlighting.

How do I debug regex that isn't matching what I expect?+

Common issues: escaping special characters (. * + ? [ ] ( ) { } ^ $ | ) - use backslash . Forgetting anchors - /test/ matches "testing" (use ^test$ for exact match). Wrong flags - case sensitivity (add i flag). Greedy vs lazy - .* vs .*?. Character class mistakes - [a-Z] is wrong (use [a-zA-Z]). Debugging steps: start simple, add complexity incrementally. Test with online tool (this tool!). Use verbose mode if available. Check documentation for your regex flavor (JavaScript vs Python vs PCRE differ). Test edge cases. Use visualization tools. This tool provides live highlighting, match explanation, and error messages for syntax issues.

Related tools

This tool is provided for informational and educational purposes only. All processing happens in your browser — no data is sent to or stored on our servers. While we strive for accuracy, we make no warranties about the completeness or reliability of results.