Skip to main content
RT

Regex Tester

Write a regular expression, paste in real text, and watch every match highlight live — with full capture-group detail for each hit.

Did you like the tool? Thanks!
Share:
/

How to Use Regex Tester

Type a pattern into the Pattern field, tick the flags you need (g, i, m, s), then paste or type your test string underneath. Matches highlight directly inside the text as you type, and a table below lists every match's position, full text, and any capture groups. An invalid pattern shows a clear inline error instead of breaking the page. Everything runs in your browser — the pattern and test string are never sent to a server.

About Regex Tester

A regular expression (regex) is a compact language for describing a shape of text rather than a literal string — "match an email address", "find any line starting with a number", "strip HTML tags" — instead of matching one fixed word. It is built into almost every programming language, most text editors, and tools like grep, so learning to read one pays off well beyond a single project. The trouble with regex is that it is notoriously easy to get subtly wrong: a pattern that looks right can fail to match an edge case, match too much, or in rare cases run so slowly on certain inputs that it locks up a page. A live tester closes that feedback loop — you see exactly what a pattern catches and misses before it goes anywhere near production code. This tool treats your test string as a JavaScript regular expression would, because that is what actually runs behind the scenes: your pattern is compiled with `new RegExp()` and executed against the text using the same engine a browser uses. The four flags map directly onto JavaScript's own flag set. "g" (global) finds every match in the string rather than stopping at the first one — this tool always searches globally internally so the match table is complete, regardless of whether you've ticked it, but leaving it off changes how capture groups behave in some downstream code, so it is still worth testing with your intended flag combination. "i" makes the match case-insensitive, so `[a-z]` also matches `A`–`Z`. "m" (multiline) changes what `^` and `$` mean: without it they anchor to the very start and end of the whole string; with it, they anchor to the start and end of each line. "s" (dotAll) makes `.` match newline characters too, which it otherwise does not — a frequent source of "why doesn't my pattern match across lines" confusion. Capture groups — the parenthesised parts of a pattern, like `(\d{4})-(\d{2})-(\d{2})` for a date — are what let you pull specific pieces out of a match rather than just confirming a match happened. The match table lists each group's captured text in order, so you can immediately check that group 1 really is the year and not, say, an empty optional group that shifted the numbering. Non-capturing groups, written `(?:...)`, are used purely for grouping alternation or repetition without adding an entry to that list — useful when you need structure but do not need the substring back. Because the whole point of this tool is to compile arbitrary user-supplied patterns, it deliberately never uses `eval()` or `new Function()` anywhere — `new RegExp()` is a data constructor, not code execution, so there is no script-injection risk from typing a pattern. The test string is HTML-escaped before matches are wrapped in a highlight tag, so pasting in text that happens to contain `<script>` or other markup cannot alter the page.

Details & Tips

Quick reference for the syntax this tester understands (standard JavaScript/ECMAScript regex): • `.` any character (except newline, unless the "s" flag is on) • `\d` `\w` `\s` digit / word character / whitespace — capitalised forms (`\D` `\W` `\S`) negate them • `[abc]` any one of a, b, c — `[^abc]` anything except those • `*` `+` `?` zero-or-more, one-or-more, zero-or-one of the preceding token • `{n,m}` between n and m repeats, `{n}` exactly n, `{n,}` n or more • `^` `$` start / end of string (or line, with the "m" flag) • `(...)` capture group, `(?:...)` non-capturing group, `(?<name>...)` named group • `|` alternation ("or"), `\` escapes a literal special character • `(?=...)` `(?!...)` lookahead / negative lookahead — match a position without consuming it Common patterns to try: email-like strings with `[\w.+-]+@[\w-]+\.[a-zA-Z]{2,}`, a UK-style postcode outline with `[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}`, or hex colour codes with `#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})`. Edge cases this tool handles explicitly: a syntax error in the pattern (an unclosed bracket, a bad backreference) is caught and shown as a readable error rather than a blank screen or console exception. Zero-length matches — patterns like `\b` or `a*` that can match an empty string — are handled without looping forever, by advancing the search position by one character whenever a match has no length. Extremely "catastrophic" patterns (heavily nested quantifiers like `(a+)+$` against a long non-matching string) can still be slow in any regex engine, this one included, because that is a property of the pattern itself, not the tester — if a match never appears to finish, simplify the pattern before assuming the tool is broken. A note on capture groups and the match table: if a group is optional and did not participate in a particular match (e.g. `(foo)?`), it shows as empty in that row rather than being silently dropped, so the group count stays consistent across all matches — useful when you are about to feed captured groups into code that expects a fixed number of columns.

Frequently Asked Questions

What flavour of regex does this tool use?
JavaScript (ECMAScript) regular expressions, the same engine built into every modern browser. Syntax is very close to PCRE (used by PHP, Python re, etc.) but not identical — for example, JavaScript did not support lookbehind assertions until relatively recently, and some Unicode property escapes need the "u" flag, which this tool does not currently expose.
Why does it say "0 matches" even though I can see the text in my string?
Your pattern is being interpreted as regex syntax, not a literal search. Special characters like `.`, `*`, `+`, `(`, `)`, `[`, `]` mean something specific in regex — to match them literally, escape them with a backslash, e.g. `\.` to match an actual period.
What does the "g" flag actually change if the tool already finds every match?
The match table and highlighting always show every match regardless of the flag, so you can visually confirm your pattern. The flag still matters for how you use the pattern in your own code — some methods (like `String.replace`) only affect the first match unless "g" is set.
My pattern is valid but the page seems to hang — what happened?
Certain patterns (heavily nested repetition like `(a+)+b` tested against a long string with no "b") can cause "catastrophic backtracking", where the number of steps needed grows exponentially. This is a property of the regex engine in general, not specific to this tool — simplify the pattern or add more specific anchors to avoid it.
How do I match a literal dot, parenthesis, or other special character?
Escape it with a backslash: `\.` for a literal period, `\(` for a literal opening parenthesis, `\\` for a literal backslash itself.
What is the difference between `(...)` and `(?:...)`?
`(...)` is a capturing group — its matched text appears in the match table and can be referenced later. `(?:...)` groups the same way for repetition or alternation but does not capture, keeping the group list clean when you only need structure.
Does the "m" flag change what `.` matches?
No — "m" (multiline) only changes what `^` and `$` anchor to (line boundaries instead of the whole string). To make `.` match newline characters as well, use the "s" (dotAll) flag instead; they are independent and can be combined.
Is my test string or pattern sent to a server?
No. The pattern is compiled and matched entirely in your browser using JavaScript's built-in RegExp — nothing is transmitted, logged, or stored.
Can I test named capture groups like `(?<year>\d{4})`?
Yes, named groups are valid syntax and will match correctly; their captured text appears in the "Groups" column of the match table alongside any unnamed groups, in the order they appear in the pattern.
Why do empty matches only advance by one character?
Some patterns (like `a*` against a string with no "a") can match zero characters at a given position. Without special handling this would loop forever at the same spot, so the tester advances one character after every zero-length match to guarantee it finishes.
Can I use this to build patterns for PHP, Python, or another language?
You can use it as a starting point since core syntax overlaps heavily, but always re-test the final pattern in your target language — flag names, escaping rules, and some advanced features (recursion, atomic groups, possessive quantifiers) differ between regex engines.

Part of These Collections

Also Available As

regex tester, regular expression tester, regex tool, test regex online, regex match highlighter, regex capture groups, javascript regex tester

Found a Problem?

Let us know if something with Regex Tester isn't working as expected.

Thanks — we'll take a look.