Regular expression tester
Enter a pattern and flags (g / i / m / s / u) and the matches are highlighted in your text. Capture groups are listed by number and name, the replacement is previewed live, and an invalid pattern shows the engine’s error instead of breaking the page.
Input
Write the body only — no surrounding slashes.
Find every match instead of stopping at the first.
Treat upper and lower case as the same letter.
^ and $ match at the start and end of each line rather than of the whole text.
Lets . match a newline, which it otherwise never does.
Treats surrogate pairs (emoji, some CJK) as single characters and enables \u{1F600} escapes.
$1, $2 … refer to capture groups, $& to the whole match and $<name> to a named group. Write $$ for a literal $.
Common syntax
- .
- Any character except a newline (the s flag includes newlines)
- \d / \D
- A digit / anything but a digit
- \w / \W
- A letter, digit or underscore / anything else. CJK is not in \w
- \s / \S
- Whitespace (space, tab, newline) / anything else
- [abc] / [^abc]
- One of a, b, c / any character that is not one of them
- [a-z] / [0-9]
- A range inside a character class
- a* / a+ / a?
- a zero or more times / one or more / zero or one
- a{2} / a{2,} / a{2,4}
- Exactly twice / at least twice / between two and four times
- *? / +?
- Lazy. Quantifiers are greedy by default, which is why <.+> swallows a whole line
- ^ / $
- Start / end. With the m flag, of each line
- \b
- A word boundary. \bcat\b does not match concatenate
- (…) / (?:…)
- Capture a group / group without capturing
- (?<name>…)
- A named group, referred to as $<name> in a replacement
- a|b
- Either a or b. Bracket it — ^(a|b)$ and ^a|b$ mean different things
- (?=…) / (?!…)
- A position followed by / not followed by that. The lookahead is not part of the match
- \. \/ \( \[
- Escape a symbol with a backslash to match it literally
Output
Related tools
All tools- Word & character countCharacters, words, lines and reading time, counted as you type.
- Full-width / half-width converterConvert Japanese text between full-width and half-width, one character class at a time.
- Line toolsRemove duplicate and blank lines, sort, trim and number a list — in one pass.
- JSON formatter & validatorPretty-print, minify, sort keys — and point at the exact line that broke.
Highlights
- You can see where a match starts and stops
- Matches are tinted in place in your text, and adjacent matches alternate shade — so four separate one-character matches never read as one block of four. A pattern reaching further than you meant is invisible in a count and obvious on the page.
- Capture groups are shown, not implied
- Every group is listed by number and by name alongside the text it captured, which is where the actual question usually is: it matched, so why is group 2 empty? A group that took part in no matching alternative is shown as "no match", distinct from one that captured an empty string.
- A half-written pattern does not break it
- An unclosed bracket is a normal state while typing. The page keeps working and prints the engine’s own message rather than going blank or leaving the previous run’s results sitting there as though they still applied.
How to use it
Enter a pattern and flags
Type the pattern body — no surrounding slashes — and tick the flags underneath: g for every match, i to ignore case, and so on. "Insert sample" fills in a date pattern and some text to run it against.
Paste the text to search
Put the text in the box below. Matches are tinted where they fall, and you get the match count together with a list of positions, matched text and capture groups.
Try a replacement
Type a replacement using $1, $& and the rest, and the rewritten text appears immediately below it. The copy button takes the result.
Where regular expressions trip people up
- Quantifiers are greedy by default
- * and + take as much as they can while still allowing a match, so <.+> does not match one tag — it runs from the first < on the line to the last >. Add a ? (<.+?>) to stop at the first opportunity. This is the single most common misunderstanding. The other fix is to spell out what may not appear — [^>]+ — which backtracks far less and stays fast on long input.
- \w and \d are narrower than they look
- \w is letters, digits and underscore only; CJK is not included, and neither are accented letters unless the pattern is written for them. For non-Latin text use explicit ranges or \S, and check the u flag when astral characters are involved. Full-width digits and letters are outside \d and \w too, so text mixing the two widths is easier to normalise before matching than to match as it stands.
- The g flag carries state
- A global regex remembers where it last stopped in its lastIndex property, so reusing the same object across calls to test() famously returns true, false, true, false on identical input. When copying a pattern into code, rebuild the object or reset lastIndex. This page builds a fresh object for every run, so the same input always gives the same answer here.
- Some patterns are pathologically slow
- Nesting one quantifier inside another — (a+)+$ is the textbook case — makes the number of attempts explode on input that does not match, and a few dozen characters can be enough to hang a thread. That is why matching here waits for a button on large input. Avoid nested repetition and constrain with character classes. It is also why running a pattern that came from an untrusted source is a denial-of-service risk: check any user-supplied pattern before compiling it.
Questions
- Which flavour of regex is this?
- The JavaScript engine built into your browser. The basics carry over to Python, PHP and Ruby, but the details — lookbehind support, flag names, whether \A and \z exist — do not. Check the target language before moving a pattern across — the treatment of newlines, the syntax for named groups and what counts as a digit are the usual differences.
- Should I include the slashes?
- No. Write only the body; /abc/g would be read as a pattern that searches for literal slashes. Flags are the checkboxes under the field. When lifting a pattern out of an editor or a config file, strip the surrounding slashes and the trailing flag letters before pasting.
- Nothing matches — where do I start?
- Check the i flag (case) and the m flag (what ^ and $ mean), then whether symbols are escaped: . and ( mean something else unescaped. Shortening the pattern until it starts matching is the reliable way to find the piece that is wrong: start with the first few characters, confirm they match, then add one condition at a time.
- Why does it stop after so many matches?
- The list is capped at 500. A pattern that matches single characters produces enormous numbers of them, and putting all of those rows on the page makes it unusable. When the cap is reached the page says so. The replacement preview is unaffected and applies throughout. The table lists the first 50, while the highlighting covers every match up to the cap.
- Is my text uploaded?
- No. Matching and replacing happen entirely in the page, so log extracts and message bodies that you would not paste into a hosted regex site are fine here. The pattern is not sent anywhere either, which matters when it encodes the shape of an internal identifier.