Regex Tester & AI Explainer AI
Test patterns live, then get a plain-English explanation from AI.
| # | Match | Capture groups |
|---|---|---|
| 1 | tayloramitverma@gmail.com | $1: tayloramitverma$2: gmail$3: com |
| 2 | hello@example.org | $1: hello$2: example$3: org |
Explain with AI
Get a plain-English, token-by-token breakdown of your pattern.
What is a regular expression?
A regular expression — regex for short — is a small language for describing patterns in text. Rather than searching for one fixed word, you describe the shape of what you are looking for: a phone number, a hex colour, a date, an email address, or the whitespace between words. Regex powers find-and-replace in editors, form validation, log parsing, URL routing, and countless data-cleaning tasks.
The trouble is that regex is famously hard to read. It is written to be compact, not communicative, and a pattern you wrote confidently in the morning can be genuinely opaque by the afternoon. This tester pairs a live, visual matcher with an AI explainer so you can both see what a pattern matches and read a plain-English breakdown of why.
How to use this tester
Enter your pattern in the expression field, toggle the flags you need, then paste sample text below. Every match is highlighted in the preview, the match count updates instantly, and any capture groups appear in the results table. When a pattern gets dense, press Explain this regex for a token-by-token walkthrough with example matches.
The most productive way to work is to build the pattern up rather than write it in one go. Start with the simplest thing that matches your target, confirm it highlights what you expect, then add one constraint at a time. Paste in text that should not match as well as text that should — a pattern that matches everything you want is only half correct if it also matches things you do not.
Common regex tokens
These are the building blocks you will reach for most often:
| Token | Matches |
|---|---|
| \d | Any digit, 0–9 |
| \w | A word character: letter, digit, or underscore |
| \s | Any whitespace (space, tab, newline) |
| \D \W \S | The negation of each of the above |
| . | Any character except a newline |
| ^ … $ | Start and end of the string (or line, with the m flag) |
| \b | A word boundary — the edge between \w and non-\w |
| * + ? | Zero-or-more, one-or-more, and optional quantifiers |
| {2,4} | Between 2 and 4 of the preceding token |
| [a-z] | A character class — any lowercase letter |
| [^a-z] | A negated class — any character that is not a lowercase letter |
| (…) | A capture group you can extract later |
| (?:…) | A non-capturing group — groups without capturing |
| a|b | Alternation — matches a or b |
Flags change everything
Flags are easy to overlook and they alter the meaning of a pattern completely. The same expression can find one match or two hundred depending on which are set.
| Flag | Name | Effect |
|---|---|---|
| g | global | Find every match rather than stopping at the first |
| i | ignore case | Match regardless of upper or lower case |
| m | multiline | Make ^ and $ match the start and end of each line |
| s | dotall | Let . match newline characters too |
| u | unicode | Enable full Unicode handling and \p{…} property escapes |
| y | sticky | Match only from the exact current index |
The m flag is the one most often missing. Without it, ^ and $ anchor to the whole string, so a pattern intended to check each line of a log file quietly matches only the very first and last positions.
Greedy, lazy, and the classic HTML mistake
By default, quantifiers are greedy: they consume as much text as possible and then give characters back only if the rest of the pattern fails. This produces the single most common regex surprise.
<.+> → matches the ENTIRE string in one go
<.+?> → matches <b>, </b>, <i>, </i> separately
Adding ? after a quantifier makes it lazy, stopping at the first position where the rest of the pattern can match. Often the cleaner fix is to be explicit about what you do not want: <[^>]+>says “anything that is not a closing bracket”, which is both faster and clearer than relying on laziness.
Capture groups and replacement
Parentheses do two jobs: they group part of a pattern, and they capture what that part matched so you can use it afterwards. Groups are numbered from left to right by their opening bracket, with group 0 being the whole match.
Input: 2026-08-18
Replace: $3/$2/$1
Result: 18/08/2026
When a pattern has several groups, numbering becomes a liability — insert one group near the front and every later reference shifts. Named groups solve this: (?<year>\d{4}) can be referenced as $<year> in a replacement and read as match.groups.year in JavaScript. If you are grouping purely for alternation or quantification and do not need the captured text, use a non-capturing group (?:…) to keep the numbering clean.
Handy example patterns
| Goal | Pattern |
|---|---|
| Email address (pragmatic) | \b[\w.+-]+@[\w-]+\.[\w.]+\b |
| Hex colour | #(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b |
| ISO date | \d{4}-\d{2}-\d{2} |
| URL slug | ^[a-z0-9]+(?:-[a-z0-9]+)*$ |
| Strip extra spaces | \s{2,} |
| Leading/trailing whitespace | ^\s+|\s+$ |
| HTML tag | <[^>]+> |
| Duplicate word | \b(\w+)\s+\1\b |
| IPv4-shaped address | \b(?:\d{1,3}\.){3}\d{1,3}\b |
| Quoted string | "(?:[^"\\]|\\.)*" |
Treat these as starting points rather than finished validators. The email pattern above accepts the addresses you will meet in practice; it is not a complete implementation of the RFC, and no reasonable regex is.
When not to use a regex
Regex is superb at matching flat, local patterns and genuinely bad at anything with nesting or structure. Knowing where the line falls saves a lot of wasted effort.
- Parsing HTML or XML. These formats nest arbitrarily deep, and regular expressions cannot count nesting. Use a real parser —
DOMParserin the browser, a library on the server. - Parsing JSON. Same reason, and
JSON.parsealready exists and is correct. - Validating email for real. The only reliable test that an address works is sending mail to it. Use a loose pattern to catch typos, then verify by email.
- CSV with quoted fields. Quoting, escaping, and embedded newlines defeat the naive patterns quickly. Use a CSV parser.
- Anything a simple string method does.
includes,startsWith, andsplitare clearer and faster than a regex when they suffice.
Catastrophic backtracking
A pattern with nested quantifiers over overlapping character sets — the classic shape being (a+)+b — can take exponential time on input that almost matches. On a server handling user-supplied input this turns a regex into a denial-of-service vulnerability, known as ReDoS. If a pattern must run on untrusted input, keep quantifiers from nesting, prefer explicit negated character classes over .*, and test with a long non-matching string before shipping.
Flavours differ
This tester uses the JavaScript (ECMAScript) engine — the same one in your browser and in Node.js. Most core syntax is shared across languages, but the details diverge. PCRE and Python support recursion, possessive quantifiers, and atomic groups that JavaScript does not; lookbehind is supported in modern JavaScript but not in every runtime you might target; and named group syntax varies between flavours. If you are writing a pattern for Python, Java, Go, or a database engine, confirm it there before relying on results from here.
AI explanations are a starting point
Only the pattern and its flags are sent for explanation — never your test text. AI-generated explanations can be incomplete or wrong, so treat them as a way to build intuition and confirm behaviour with the live matcher and your own test cases. See the disclaimer and privacy policy.