Regex tester
2 matches
Runs in your browser · nothing is uploaded
Type a pattern and it runs against your text as you type: matches highlighted in place, capture groups listed with their positions, and a plain-English reading of what each piece of the pattern does. Replace and split are the same pattern applied a different way, and Escape a literal runs the other direction: text in, every metacharacter backslashed, ready to drop into a pattern.
How to use the regex tester
This uses the browser’s own regular-expression engine, which is the same one your JavaScript will run against, so a pattern that works here works in your code, and one that does not will not. That is worth knowing because regex flavours genuinely differ: lookbehind, \p{…} properties and named groups all behave differently in PCRE, Python and POSIX, and a pattern copied from a PHP answer may simply not compile here.
One pattern shape is refused rather than run. A quantifier nested inside a quantified group: (a+)+, (\d+)*. Can take exponential time on input that nearly matches, and because the engine runs on the same thread as the page there is no way to interrupt it: the tab stops responding and the only fix is closing it. Rather than let that happen, the pattern is rejected with an explanation. The fix is almost always to make the inner quantifier possessive in spirit: match a specific character class instead of nesting repetition.
The explanation panel walks the pattern and names each piece. It is a reading aid, not a parser: it does not build a tree or tell you what the pattern means as a whole, and it will not catch a logic error. It is there for the case everyone actually has, which is inheriting a pattern from a colleague and needing to know what (?<=\s) was for.
Twelve characters carry meaning inside a pattern and have to be escaped with a backslash to match themselves: . * + ? ^ $ { } ( ) | [ ], along with the backslash, the forward slash where a pattern is written between slashes, and the hyphen inside a character class, where an unescaped one means a range. That is worth more than convenience. Building a pattern by concatenating user input is the regex equivalent of building SQL by concatenation: a search box that drops what someone typed into a new RegExp can be handed (a+)+$ and made to hang the process, which is the same shape this tester refuses. RegExp.escape reached browsers only recently, which is why nearly every codebase still carries its own copy of the same one-line function: s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), a backslash in front of every character that would otherwise mean something. Escape a literal, above, is that function with a box around it: paste the text that has to match itself and take the escaped form out. Use the panel when you are assembling a pattern by hand, and the line when the escaping has to happen at runtime in your own code.
What people use it for
- Checking a pattern against real text before it goes near production
- Reading a pattern someone else wrote
- Testing a replacement with capture groups in it
- Splitting a line on a pattern to see what falls out
- Escaping a literal string so it can go into a pattern and match itself
- Working out why a match is longer than expected
Questions
Yes, it is the browser’s own RegExp. A pattern that works here works in your code.
It nests a quantifier inside a quantified group, like (a+)+. That shape can take exponential time and freeze the tab, so it is rejected instead of run.
No. Type only the pattern; the slashes and flags are shown around the box.
The twelve metacharacters . * + ? ^ $ { } ( ) | [ ] and the backslash, plus the hyphen inside a character class and the slash if you write the pattern between slashes.
Escape every metacharacter in it before it goes into the pattern. Escape a literal, above, does exactly that. In code it is RegExp.escape where it is available, and a hand-rolled replace where it is not.
It puts a backslash in front of every character that would otherwise mean something to the engine, so the result matches itself and nothing else. price: $9.99 (50% off) comes back as price: \$9\.99 \(50% off\). It is one-way; there is no unescape.
Quantifiers are greedy by default. Add a question mark, so .*? rather than .*, to stop at the first match instead of the last.
Use $1, $2 for numbered groups and $<name> for named ones, exactly as in String.replace.
With \n, or \r\n for Windows text. The dot does not match a line break unless the s flag is on.
It makes ^ and $ match at every line rather than only at the start and end of the whole subject.
Yes, in current browsers. Both are relatively recent additions, so a pattern using them may not run in an older runtime.
Usually, but not always. Lookbehind, possessive quantifiers and some escapes differ between flavours.
An empty pattern matches an empty string at every position, so with the g flag you get one match per character boundary. Those show as "(empty match)".
No. Everything runs in your browser, which matters when you are testing against real log lines.