Skip to content
Tools

Regex Tester

Test regular expressions instantly with live matching, captured groups, replacement preview and detailed explanations. Everything runs locally in your browser.

Visible pane

Test text

119 chars

Loading editor…

Waiting for input

Everything runs locally in your browser. Your data is never uploaded.

What is a regular expression?

A regular expression is a small pattern language for describing shapes of text. Instead of searching for one fixed string, you describe what you are looking for — three digits, then a hyphen, then four digits — and the engine finds every piece of text that fits.

The pattern is built from ordinary characters that match themselves, plus a handful of characters with special meaning. a matches the letter a. \d matches any digit. +means “one or more of the thing before me”. Put together:

Matches a UK-style postcode
[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}

Regular expressions are supported almost everywhere — JavaScript, Python, Go, Java, grep, your editor’s find box — with small differences in syntax between them. This tester uses the JavaScript flavour, which is what runs in browsers and Node.js.

They are excellent at finding and extracting patterns in flat text, and genuinely bad at anything that nests. A regular expression cannot count how deeply brackets are nested, which is why they cannot parse HTML or JSON no matter how clever the pattern gets. Use something that parses instead — the HTML formatter builds a real document tree, and a JSONPath tester queries JSON by its structure rather than by the shape of its text.

How to use Regex Tester

  1. 1. Type a pattern. Enter it in the field between the two slashes. There is no need to escape the delimiters — write the pattern exactly as it appears between / and / in code.
  2. 2. Choose your flags. The six buttons to the right toggle global, ignore case, multiline, dot all, unicode and sticky. Hover any of them to see what it changes.
  3. 3. Add test text. Paste it, drop a file onto the page, or load one of the built-in samples. Every match is highlighted as you type, with the selected one picked out.
  4. 4. Read the matches. Each entry shows its position, its length and every capturing group it produced. Click one to jump to it in the text, or step through them with the arrows.
  5. 5. Check the explanation. The Explanation tab breaks your pattern into its parts and describes each one, which is the fastest way to find the piece that is not doing what you expected.
  6. 6. Try a replacement. Open the replacement preview to see the result of a substitution, using $1 and $<name> to reference groups. Your test text is never modified.

Regex syntax explained

Almost every pattern you will write is built from the pieces below. The tester explains whichever ones your pattern uses, so this is a reference rather than something to memorise.

Characters

.
Any character except a newline, unless the s flag is on.
\d \D
A digit, or anything that is not a digit.
\w \W
A letter, digit or underscore — or anything that is not.
\s \S
Whitespace, or anything that is not whitespace.
\n \t
A newline, or a tab.
\.
A literal dot. Any special character can be escaped this way.

Sets and ranges

[abc]
Any one of a, b or c.
[a-z]
Any character in the range a to z.
[^abc]
Any character except a, b or c.
\p{L}
Any letter in any script. Needs the u flag.

Quantifiers

*
Zero or more.
+
One or more.
?
Zero or one — makes the previous part optional.
{3} {2,} {2,5}
Exactly three, at least two, or between two and five.
*? +? ??
The lazy form: match as few characters as possible.

Anchors and boundaries

^
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 \B
A word boundary, or a position that is not one.

Groups and alternation

(…)
Capturing group — remembers what it matched.
(?:…)
Non-capturing group — groups without remembering.
(?<name>…)
Named capturing group, read back as $<name>.
a|b
Either a or b.
\1 \k<name>
Backreference to what a group matched earlier.

Lookaround

(?=…)
Followed by, without consuming it.
(?!…)
Not followed by.
(?<=…)
Preceded by, without consuming it.
(?<!…)
Not preceded by.

Regex flags

Flags change how the whole pattern is applied. They are the letters after the closing slash in /pattern/gi.

g
GlobalFind every match rather than stopping at the first one.
i
Ignore caseMatch letters regardless of upper or lower case.
m
Multiline^ and $ match at the start and end of each line, not just the whole text.
s
Dot allLet . match newline characters as well as everything else.
u
UnicodeTreat the pattern as a sequence of code points, enabling \p{…} and \u{…}.
y
StickyMatch only at the exact position where the previous match ended.

Common regular expressions

Every pattern below is in the tester’s Library tab — one click loads it with sample text. Each note says what the pattern does not cover as well as what it does, because a copied regex is usually trusted further than it deserves.

Email

/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/gi

Catches the shape of an ordinary address. It deliberately does not implement RFC 5322, which allows quoted strings and comments almost nobody sends.

URL

/https?:\/\/[^\s/$.?#].[^\s]*/gi

Matches http and https URLs inside running text. Stops at the first whitespace, so trailing punctuation may be included.

Phone number

/\+?\d{1,3}[\s.-]?\(?\d{2,4}\)?[\s.-]?\d{3,4}[\s.-]?\d{3,4}/g

A permissive international shape. Phone numbering rules vary by country, so treat this as a first pass rather than validation.

IPv4 address

/\b(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\b/g

Each octet is bounded to 0–255, so 999.1.1.1 is correctly rejected.

IPv6 address

/(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}|::(?:[A-Fa-f0-9]{1,4}:){0,6}[A-Fa-f0-9]{1,4}/g

Covers full form and leading-:: shorthand. Fully general IPv6 with :: anywhere needs a longer alternation.

Date (ISO)

/\b(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])\b/g

Matches YYYY-MM-DD with month and day in range. It does not know that 2026-02-31 is not a real date.

Time (24-hour)

/\b([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?\b/g

Hours 00–23 with optional seconds. The third group is the seconds when present.

Username

/^[a-z0-9_](?:[a-z0-9_.-]{1,18})[a-z0-9_]$/gim

Three to twenty characters, starting and ending with a letter, digit or underscore, so a trailing dot or hyphen is rejected.

Regex best practices

  • Anchor when you mean the whole string. Without ^ and $, a validation pattern will happily match a fragment buried in a longer string — which is how invalid input passes validation.
  • Never nest one quantifier inside another. (a+)+ gives the engine exponentially many ways to split the same text, and a few dozen characters can hang a process for years. This is catastrophic backtracking, and it is the most common way a regex takes down a server.
  • Prefer a character class to an alternation of single characters. [abc] is faster and clearer than (a|b|c), and it does not create a capturing group you did not want.
  • Use non-capturing groups when you are not capturing. (?:…) keeps your group numbers meaningful, so $1 still refers to what you think it does after you add a group for precedence.
  • Reach for lazy quantifiers when matching delimiters. <.*> swallows everything to the last > on the line; <.*?> stops at the first.
  • Do not validate email addresses with a regex. The full RFC 5322 grammar is far larger than anything worth writing, and every shortened version rejects addresses that really work. Check for an @ with something either side, then send a confirmation message.
  • Comment anything non-obvious. JavaScript has no x flag for whitespace and comments inside patterns, so leave the explanation beside the pattern in your code. You will not remember it in six months.
  • Test the near misses, not just the hits. A pattern that matches every valid input is only half working — check that it rejects the invalid ones too. Every sample in the library includes examples that should not match.

Frequently asked questions

Is this Regex Tester free?

Yes. Live matching, capturing groups, the replacement preview, the pattern explanation and the library are all free, with no account and no usage limit.

Is my text uploaded anywhere?

No. Patterns run in your browser using its own JavaScript regex engine. The pattern and the test text are never sent over the network, never stored and never logged. Disconnect after the page loads and it keeps working.

Which regex flavour does it use?

JavaScript's, as defined by ECMAScript. That is what runs in browsers and in Node.js. Most syntax is shared with PCRE, but a few things differ: JavaScript has no possessive quantifiers or atomic groups, and \A, \z and \Z are not supported — use ^ and $ instead.

What are regex flags?

Modifiers that change how the whole pattern behaves. Global (g) finds every match instead of stopping at the first, ignore case (i) makes letters case-insensitive, multiline (m) makes ^ and $ match at line boundaries, dot all (s) lets . match newlines, unicode (u) enables \p{…} and proper code-point handling, and sticky (y) forces each match to begin exactly where the last one ended.

What are capturing groups?

Parentheses that remember the text they matched so you can read it back. Group 1 is the first opening parenthesis, group 2 the second, and so on. Name them with (?<name>…) to refer to them by label instead of by number, and use (?:…) when you want grouping without capturing.

Can I replace text using regex?

Yes. Open the replacement preview and type your replacement. Use $1, $2 and so on to insert captured groups, $<name> for named groups, $& for the whole match and $$ for a literal dollar sign. The preview updates as you type and never modifies your original text.

Can I upload text files?

Yes. Use the upload button or drag a text file onto the tool. Files up to 5 MB are read locally with the browser's FileReader — nothing is transmitted.

Why did my pattern time out?

It was almost certainly backtracking catastrophically. Patterns with nested quantifiers, such as (a+)+ or (a|a)*, can take exponentially longer as the text grows — a few dozen characters is enough to hang a browser for years. Matching runs in a background worker that is stopped after one second, so a runaway pattern costs you a second rather than the page.

How do I avoid catastrophic backtracking?

Make sure the inner and outer parts of a repetition cannot match the same text. (a+)+ is dangerous because the engine has many ways to split the same run of a's; [a]+ or a+ is not. Anchor patterns where you can, prefer character classes to alternations of single characters, and be careful with .* next to another quantifier.

Why does my pattern match an empty string over and over?

Patterns that can match nothing — a*, (b?) — produce zero-length matches at every position. They appear in the match list with a length of zero and no highlight, because there is no text to paint. Add a + or require at least one character if that was not intended.

What is the difference between greedy and lazy quantifiers?

A greedy quantifier such as .* takes as much as it can and then gives characters back until the rest of the pattern fits. Adding a question mark makes it lazy — .*? takes as little as possible and expands only as needed. For matching an HTML tag, <.*> greedily runs to the last > on the line, while <.*?> stops at the first.

Can regex parse HTML or JSON?

No, and it is worth being firm about this. Both formats nest arbitrarily deeply, and regular expressions cannot count nesting. Use regex to scan for a pattern inside HTML or JSON, never to parse it — for JSON there is a dedicated formatter and validator on this site.

Does it support lookahead and lookbehind?

Yes. Lookahead (?=…) and negative lookahead (?!…) have always been supported; lookbehind (?<=…) and negative lookbehind (?<!…) are supported in every browser this site targets. All four assert without consuming characters, so they do not appear in the match.

How many matches will it show?

The list is capped at 5,000 so a broad pattern on a large file cannot lock the page. The total count above it is always the true number, and the status bar tells you when the list has been trimmed.

Does it work offline?

Once the page has loaded, yes. Everything runs locally, so you can disconnect and keep testing. You only need a connection to load the page in the first place.

Popular tools

↑ ↓NavigateOpenEscClose