Regex Tester
Test JavaScript regex with live match highlighting & groups.
Regex Tester
How was your experience with this tool?
Found a bug? Missing a feature? Tell us — it takes 10 seconds.
See how it works
Watch a quick simulation of this tool in action — no file needed.
How to use Regex Tester
Follow these steps — everything happens instantly in your browser.
- 1
Step 1. Enter your regex pattern (without the surrounding slashes).
- 2
Step 2. Toggle the flags you need (g, i, m, s, u, y).
- 3
Step 3. Type or paste the text to test against.
- 4
Step 4. Review the highlighted matches and the per-match group table.
Regex Tester: Understanding Flags, Groups, and the g-Flag Trap
The same pattern, six different behaviors depending on the flags
A regex pattern by itself is incomplete — the flags attached to it fundamentally change what it matches and how. `/foo/` and `/foo/gi` aren't the same search with different verbosity; they're different matching behaviors entirely. This tool uses JavaScript's native RegExp engine — the same one running in your browser's JavaScript and in Node.js — so whatever pattern and flag combination works here will behave identically in real code, which is exactly the point of testing against a live engine rather than a simplified regex simulator.
What each flag actually changes
| Flag | Name | Effect |
| --- | --- | --- |
| g | Global | Finds all matches instead of stopping at the first |
| i | Case-insensitive | Ignores letter case when matching |
| m | Multiline | `^` and `$` match line boundaries, not just string start/end |
| s | Dotall | `.` matches newline characters too |
| u | Unicode | Enables full Unicode code point matching (important for characters outside the basic multilingual plane) |
| y | Sticky | Matches only starting at the exact lastIndex position, not anywhere later in the string |
Testing a pattern
Enter your regex pattern (without the surrounding slashes).
Toggle the flags you need: g, i, m, s, u, y.
Type or paste the text to test against.
Review the highlighted matches and the per-match group table.
The g-flag bug that trips up real code
This is worth understanding even outside this tool, because it's a genuine JavaScript gotcha: when a RegExp has the `g` flag, calling `.exec()` repeatedly on the same regex object advances an internal `lastIndex` property, so each call picks up where the last one left off. This is how you get all matches in a loop — but it also means calling `.exec()` on a `g`-flagged regex just once, expecting it to behave like a non-global match, returns only the first result and silently leaves `lastIndex` in a non-zero state for the next call.
If you've ever seen a `g`-flagged regex `.match()` or `.exec()` mysteriously return only one result outside of a loop, this internal `lastIndex` state advancing is almost always why. This tool handles that internally so the match list you see here always reflects every match in your input, regardless of how the underlying exec loop works.
Reading the capture group table
Each match shown includes its capture groups as an ordered list matching the order your parentheses appear in the pattern. A group defined with `?` for optionality — like `(a)?` — can legitimately not participate in a given match, and when that happens, the tool shows `(undef)` rather than an empty string, which matters: `undefined` and `''` are genuinely different values in JavaScript, and code relying on `match[1] === undefined` to detect a non-participating group would break if the tool silently substituted an empty string instead.
Common mistakes
Forgetting the `g` flag and being confused why only one match highlights, when the pattern is otherwise correct.
Using `.` expecting it to match newlines by default — it doesn't, unless the `s` (dotall) flag is set.
Assuming `^` and `$` anchor to the whole string when testing multi-line input — without the `m` flag, they only match the very start and end of the entire string, not each line.
Writing a pattern with unbounded repetition against ambiguous input (like nested quantifiers) that can produce catastrophic backtracking — if matches seem to hang or the 5,000-match cap kicks in unexpectedly, the pattern itself may need restructuring.
Why there's a 5,000-match cap
Certain regex patterns — particularly zero-width matches, like a lookahead with no actual character consumption — can technically match an unbounded number of times against ordinary input, which would freeze the page trying to enumerate them all. Capping at 5,000 matches per test run keeps the tool responsive even against a pathological pattern, while still being far more than enough to validate a pattern's correctness against realistic test text.
Real use cases
Validating an email or phone-number pattern against a batch of sample inputs before shipping it in form validation code.
Debugging why a production regex isn't matching expected text, using live highlighting to see exactly what it does match.
Extracting structured data from log lines using capture groups, and confirming the group order before writing the parsing code.
Testing a find-and-replace pattern's matches before running it against a large codebase or dataset.
Frequently asked questions
Q: Which regex flavor does this use?
A: JavaScript's native RegExp — the same engine that runs in your browser and in Node.js. Patterns that work here will work identically in your JS code.
Q: What does each flag mean?
A: g = global (all matches), i = case-insensitive, m = multiline (^/$ match line boundaries), s = dotall (. matches newlines), u = unicode, y = sticky.
Q: Why does my regex with the g flag return only one match elsewhere?
A: With the g flag, `RegExp.exec()` and `.match()` advance an internal `lastIndex` property between calls. This tool handles that internally so you always see every match in the input, regardless of how a manual exec loop is written.
Q: Can I see capture groups?
A: Yes — each match row shows all capture groups as an ordered list. Groups that didn't participate in a match, such as from `(a)?` not matching, show `(undef)`.
Q: Is there a match limit?
A: The tool caps at 5,000 matches per test to prevent runaway patterns, like zero-width matches, from freezing the page.
Q: Why doesn't `^` match the start of every line in my multi-line text?
A: By default, `^` and `$` only anchor to the start and end of the entire input string. Enable the `m` (multiline) flag to have them match at each line boundary instead.
Test your pattern now
Try your regex on the Regex Tester. Validating structured data instead? Check the JSON Formatter. Working with encoded text? Try URL Encode / Decode or Base64 Encode / Decode.
Want the extended step-by-step tutorial? Read it here.
Why use this tool
Private by design
All processing happens locally in your browser. Open DevTools → Network and you'll see zero file uploads. Ever.
Instant
No upload wait, no queue, no server round-trip. Results appear the moment you drop a file.
Free & unlimited
No accounts, no watermarks, no daily caps. Use it as many times as you like, forever.
Works everywhere
Desktop, tablet or phone — every tool is responsive and installable as a PWA for offline use.
Frequently asked questions
Everything you might want to know about regex tester.
❤️ This tool is free — forever.
Sharing it helps more people discover it, and ad revenue from visitors is what keeps it free. No accounts, no catch.
JSON Formatter
Beautify, minify and validate JSON — 100% in your browser.
URL Encode / Decode
Percent-encode or decode URLs and query strings — locally.
Base64 Encode / Decode
Convert text to and from Base64 — Unicode-safe, no uploads.
Markdown Preview
Write Markdown and see the rendered HTML live — side by side.