⚡ 10-second version
Write the pattern at tooladda.online/regex-tester.html and watch matches highlight as you type — with every capture group broken out and its exact character position shown. Paste production log lines safely; nothing is uploaded.
❗ Important
The text you test against is usually real data — log lines, customer records, a CSV export. All matching runs locally in your browser, so pasting genuine data here doesn't ship it anywhere.
💥 Catastrophic backtracking: the regex that hangs your server
This is the most important regex concept almost nobody is taught, and it's a real availability bug (ReDoS).
Consider this innocent-looking pattern:
^(a+)+$
Run it against aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa! — thirty as and one !.
The ! means the match must fail. But before giving up, the engine tries every possible way to divide those thirty as between the inner a+ and the outer +. That's an exponential number of combinations. Add one more a and the work doubles.
| Input length | Backtracking attempts | Time |
|---|---|---|
20 as + !
|
~1 million | milliseconds |
25 as + !
|
~33 million | ~a second |
30 as + !
|
~1 billion | ~a minute |
40 as + !
|
~1 trillion | 🔥 effectively forever |
Where this bites in real code: a regex validating a user-supplied email or URL, in a request handler. An attacker sends a 50-character string crafted to trigger it, and one CPU core is pinned. A handful of requests take your service down — no exploit, no privilege, just a bad pattern.
The tell: nested quantifiers where the inner and outer can match the same thing — (a+)+, (a*)*, (\w+\s?)+, (.*),?. Rewrite them so only one thing can consume each character: ^a+$ does the job above, instantly.
Greedy vs lazy, on one string
Against <div><span>hi</span></div>:
| Pattern | Matches | Why |
|---|---|---|
<.+> |
<div><span>hi</span></div> |
Greedy — takes everything, then backs off just enough |
<.+?> |
<div> |
Lazy — takes the least it can get away with |
<[^>]+> |
<div> |
🏆 Best — can't cross a > at all, so no backtracking |
That third form is the professional habit: instead of adding ? to make a greedy quantifier behave, use a character class that cannot over-match in the first place. It's faster and it can't blow up.
🧭 How it works
✨ What's inside
| ### 🎨 Live highlighting Matches light up as you type. Regex is a feedback-loop skill — seeing the effect of each character is how you actually learn it. | ### 🔢 Groups broken out Numbered and **named** groups (`(?\d{4})`) listed separately per match, so you stop counting parentheses to find group 3. |
| ### 📍 Match positions Start index and length for each match — what you need when you're slicing strings in code rather than just testing a pattern. | ### 🔁 Replace mode Preview substitutions with `$1`, `$` backreferences before running them across a real file. |
🛠️ Real jobs
| Situation | What you do |
|---|---|
| 🔍 Parsing log lines | Build a pattern that pulls timestamp, level and message into groups. |
| ✅ Input validation | Test the edge cases — and check for nested quantifiers before shipping. |
| 🔁 Bulk find-and-replace | Get the replacement right here before running it across a codebase. |
| 📊 Extracting fields from messy text | Named groups make the extraction readable six months later. |
| 🧪 Debugging someone's regex | Paste it in and see what it actually matches versus what the comment claims. |
| 🎓 Learning regex | Live feedback beats reading a syntax table. |
📖 Four steps
1. Open → tooladda.online/regex-tester.html
2. Pattern → type it; watch matches highlight live
3. Flags → g (all matches) · i (case-insensitive) · m (multiline)
4. Check → groups, positions, and replace preview
▶ Test now — tooladda.online/regex-tester.html
💡 Tip
Test the failure cases, not just the ones that should match. A pattern that matches valid input and also matches garbage is worse than no validation, because it creates false confidence. And always include an input designed to not match — that's where backtracking blowups reveal themselves.
⚠️ Warning
Do not use regex to parse HTML, JSON or CSV. They're nested/quoted structures and regex is not; you'll get something that works on your ten samples and breaks in production. Use a real parser — for CSV, the CSV to JSON converter handles the quoting rules properly.
❓ FAQ
Is it free? Is my data uploaded?
Free, no signup, and nothing is uploaded — matching runs in your browser's own regex engine.
Which regex flavour is this?
JavaScript (ECMAScript). Very close to PCRE for everyday patterns; lookbehind and some Unicode property escapes differ between engines, so verify if you're targeting Python or PHP.
Why does my regex hang the page?
Catastrophic backtracking from nested quantifiers like (a+)+. Rewrite so only one part can consume each character.
Greedy or lazy?
Better than either: use a negated character class so over-matching is impossible — <[^>]+> rather than <.+?>.
What does the g flag change?
Without it you get the first match only. With it, all of them. It's the flag people forget when a replace only fixes the first occurrence.
Can I use named groups?
Yes — (?<name>...), listed by name in the results and usable as $<name> in replacements.
How do I match a literal dot?
Escape it: .. An unescaped . matches any character, which is why a.b happily matches axb.
🔬 Under the hood
- Uses your browser's native regex engine — the same one your JavaScript will run in, so results transfer exactly.
- Matching is incremental and interruptible so a pathological pattern degrades rather than freezing the tab outright.
- Covered by unit tests.
- Works offline once loaded.
Originally published on ToolAdda, where Regex Tester runs free in your browser — nothing is uploaded, nothing leaves your device.
Top comments (0)