Regex Tester
Test a regular expression against your own text, see every match and capture group, and have the pattern read back to you in plain English. No account, no waiting, and nothing you type is uploaded.
Start from
What matched
Highlighted in your textMatches
Enter a pattern and some text to see the matches.
What your pattern says
In plain EnglishType a pattern and it will be read back to you, piece by piece.
Replace matches
Result
How to use it
- Type your pattern into the box between the two slashes, or click one of the ready made patterns to start from something that already works.
- Paste the text you want to test it against. Matches highlight as you type, and every capture group is listed underneath.
- Read the What your pattern says panel. It breaks the pattern into pieces and explains each one, which is the fastest way to find the bit that is wrong.
- Open Replace matches to preview a substitution, using
$1for the first group or$<name>for a named one.
Regex cheatsheet
Everything you are likely to need, in one place. These work in JavaScript, and almost all of them work unchanged in Python, PHP, Java and most other flavours.
Characters
. | Any character except a line break |
\d | Any digit, 0 to 9 |
\D | Anything that is not a digit |
\w | A letter, digit or underscore |
\W | Anything that is not a letter, digit or underscore |
\s | Any whitespace: space, tab or line break |
\S | Anything that is not whitespace |
\n | A line break |
\t | A tab |
How many
* | Zero or more |
+ | One or more |
? | Zero or one — optional |
{3} | Exactly three |
{2,} | Two or more |
{2,5} | Between two and five |
+? | One or more, but as few as possible |
Where
^ | Start of the text, or of a line with the m flag |
$ | End of the text, or of a line with the m flag |
\b | A word boundary — the edge of a word |
\B | Not a word boundary |
Sets and groups
[abc] | Any one of a, b or c |
[^abc] | Any character except a, b or c |
[a-z] | Any character from a to z |
(abc) | A group, captured so you can reuse it |
(?:abc) | A group that is not captured |
(?<name>abc) | A group captured under a name |
a|b | Either a or b |
\1 | Whatever group 1 matched, again |
Looking around
(?=abc) | Only if abc comes next — not included in the match |
(?!abc) | Only if abc does not come next |
(?<=abc) | Only if abc came before |
(?<!abc) | Only if abc did not come before |
Flags
g | Find every match, not just the first |
i | Ignore capitalisation |
m | Make ^ and $ match at each line |
s | Let the dot match line breaks too |
u | Treat the pattern as unicode |
y | Match only from where the last match ended |
Common patterns, and what they are really worth
Each of these is one click away above. The honest notes matter as much as the patterns: a regex that looks right and quietly accepts bad input is worse than no regex at all.
Email address
/[\w.+-]+@[\w-]+\.[\w.]+/gDeliberately permissive. Validating an address perfectly with regex is not possible; send a confirmation email instead.
URL
/https?:\/\/[\w.-]+(?:\/[\w./?%&=-]*)?/gMatches http and https links including a path and query string.
US phone number
/\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}/gAccepts brackets, spaces, dots or dashes as separators.
Date (YYYY-MM-DD)
/\d{4}-(?<month>\d{2})-(?<day>\d{2})/gUses named groups, so the month and day come back labelled.
IPv4 address
/\b(?:\d{1,3}\.){3}\d{1,3}\b/gShape only — it will also accept 999.999.999.999.
Hex colour
/#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b/gMatches both the three and six digit forms.
UK postcode
/[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}/giWorks with or without the space before the last three characters.
Repeated word
/\b(\w+)\s+\1\b/giUses a back-reference: \1 means "the same word again".
HTML tag
/<\/?[a-zA-Z][^>]*>/gFine for stripping tags from simple markup. Do not parse real HTML with regex.
Runs of whitespace
/\s{2,}/gReplace with a single space to tidy up spacing.
The mistakes that catch everyone
Forgetting the g flag
Without g a pattern stops at the first match. If you are wondering why only one of your five results turned up, that is almost always why.
Greedy quantifiers eating too much
<.*> against <b>hi</b> matches the whole string, not just the first tag, because * takes as much as it can and only gives back what it must. Use <.*?> to make it lazy, or <[^>]*> to say what you actually mean.
Unescaped dots
. means any character. To match a literal full stop — in a filename or a domain — escape it as \., or example.com will happily match examplexcom.
Catastrophic backtracking
A pattern with a quantifier inside a quantifier, such as (a+)+$, can take longer than the age of the universe on a fairly short string. That is a real denial-of-service risk in production code, and on most online testers it simply freezes the tab. This one runs your pattern in a background worker and stops it after two seconds, so a runaway pattern tells you it is runaway instead of hanging.
Trying to parse HTML
Regex cannot match nested structures. It is fine for pulling simple tags out of simple markup, and wrong for anything that needs to understand the document. Use a parser.
Questions
Which flavour of regex is this?
JavaScript's, because it runs in your browser using the same engine your browser already has. The syntax on the cheatsheet above is almost entirely shared with PCRE, Python and Java. The main differences: JavaScript has no \A or \z anchors, and lookbehind is supported in all current browsers but not in very old ones.
Is my pattern or test text uploaded?
No. Everything runs in your browser, and neither the pattern nor the text ever leaves the page. That matters more than it sounds: people test regex against real log lines, customer records and API keys. See our Privacy Policy for the full position.
Do I need an account to save a pattern?
There are no accounts here at all. Your pattern, flags and test text are kept in this browser's local storage, so the page opens where you left it. Nothing is shared, and clearing site data removes it.
Why did it say my pattern was too slow?
Because it ran for two seconds without finishing. That almost always means nested quantifiers — (a+)+, (\d*)* — which make the engine try an exponential number of combinations. Rewrite the inner part so it cannot match the same text two ways, or make it more specific.
What does the number beside each match mean?
The start and end position of the match in your text, counted from zero. Handy when you are slicing the string in code afterwards.
Can I use it on my phone?
Yes. The layout works down to a narrow screen, though writing regex on a phone keyboard is its own kind of punishment.