Type a pattern, paste some text, and watch every match light up as you go. This tester runs on the browser's own JavaScript engine, so what you see here is exactly what you'll get in Node.js or front-end code. The replace preview shows the result of a substitution live, which is the fastest way to confirm a pattern before you paste it into a codebase.
Regex cheat sheet
These cover the vast majority of real-world patterns:
\d— a digit (0–9);\w— a word character (a–z, A–Z, 0–9, _);\s— whitespace..— any character except a newline.^and$— start and end of the string (or line, with themflag).*— 0 or more;+— 1 or more;?— 0 or 1.{n,m}— between n and m repetitions.[abc]— any one of a, b, or c;[^abc]— anything except those.(group)— a capture group;(?:group)— a group that doesn't capture.|— OR, as incat|dog.
The three flags you'll use constantly
Flags change how the whole pattern behaves. Three matter most:
g(global) — find every match, not just the first. Without it,replaceonly changes one occurrence.i(case-insensitive) —/hello/imatchesHello,HELLO, andhelloalike.m(multiline) — makes^and$match the start and end of each line instead of the whole string.
Combine them freely: /error/gi finds every case-insensitive occurrence of "error" in a log.
Greedy quantifiers bite when parsing tags
By default * and + are greedy — they grab as much as possible. On <a>text</a>, the pattern <.*> matches the entire string, not just the first tag, because .* swallows everything up to the last >. Add a ? to make it lazy — <.*?> stops at the first >. This one detail fixes most "my regex matches too much" bugs.
Escaping: matching characters that mean something
A bare . matches any character, so to match a literal period you escape it: \.. The same goes for the other metacharacters — + * ? ( ) [ ] { } ^ $ | \. To match a price like $4.99 you'd write \$4\.99, escaping both the dollar sign and the dot. Forgetting to escape a dot is probably the single most common regex mistake.
When NOT to use regex
Regex is the wrong tool for parsing nested structures. Don't use it to parse HTML or JSON — those formats nest arbitrarily deep, and regex fundamentally can't track that. Use a real parser (DOMParser, JSON.parse) instead. Regex shines on flat, predictable text: validating an input format, finding-and-replacing in a document, pulling fields out of a log line, or splitting a CSV row. Reach for it there, and reach for a parser everywhere else.
FAQ
What do the g, i, and m flags do?
+
g (global) finds every match instead of stopping at the first. i matches case-insensitively. m (multiline) makes ^ and $ match the start and end of each line. Combine them, e.g. gi for a global, case-insensitive search.
Why does my regex only match once without the g flag?
+
Without the global flag a regex stops at the first match — replace changes only one occurrence and matchAll requires g. Add the g flag whenever you want every match, not just the first.
Does this tester use JavaScript regex rules?
+
Yes — it runs on the browser's built-in JavaScript engine, matching Node.js and front-end behavior exactly. Other languages differ: lookbehind and some Unicode features behave differently in Python, PCRE, or Go, so a pattern may need tweaking elsewhere.
How do I match a literal special character like a dot?
+
Escape it with a backslash. A bare . matches any character, so a literal period is \.. Characters needing escaping include . + * ? ( ) [ ] { } ^ $ | and \ itself.
What is the difference between greedy and lazy matching?
+
Quantifiers like * and + are greedy by default — they match as much as possible. Adding ? makes them lazy, matching as little as possible. It matters when parsing tags or quoted strings, where greedy matching swallows too much.