Regex Tester

Test a regular expression against your own text and see every match highlighted as you type. Pick JavaScript, PCRE2 (PHP), Python, Go, or Rust, check capture groups, try a find-and-replace, and copy the finished pattern. It all runs in your browser.

Flavor
Examples
Test string
No pattern yet

Matches and their capture groups will appear here...

What is a regular expression?

A regular expression (regex) is a short pattern that describes a kind of text, like "a word followed by an @ and a domain" or "three digits, a dash, then four digits". Programs use regex to search text, check that input has the right shape, pull out pieces of data, and find and replace in bulk.

Patterns are compact but easy to get wrong, so it helps to test one on real sample text before putting it in your code.

Why use our regex tester

  • ·Five real engines. JavaScript, PCRE2 (PHP), Python, Go, and Rust each run on their own engine, not a translation into JavaScript.
  • ·Live highlighting. Matches light up as you type.
  • ·Groups by name. See what each numbered and named group captured.
  • ·Replace preview. Try a replacement in the flavor's own syntax before running it for real.
  • ·Never freezes. Runaway patterns are stopped after a moment instead of locking up the tab.
  • ·Private. Your pattern and text never leave your browser.

How to test a regex

  1. 1

    Pick the regex flavor

    Choose JavaScript, PCRE2 (PHP), Python, Go (RE2), or Rust from the Flavor menu. JavaScript is ready at once. The others download their engine the first time you pick them.

  2. 2

    Type your regular expression

    Enter the pattern on its own, without the slashes or quotes your code puts around it, or pick one from the Examples menu to start from a working pattern.

  3. 3

    Turn on the flags you need

    Each flavor shows its own flags, such as g, i, m, and s. Hover over a flag to see what it does.

  4. 4

    Paste your test text

    Matches are highlighted as you type, and the count of matches shows under the text.

  5. 5

    Check groups or try a replace

    Open Match details to see each match and its groups, or switch to Replace, type the new text, and see the result with every change highlighted.

Regex flavors: JavaScript, PCRE2 (PHP), Python, Go, and Rust

A regex flavor is one language's version of regular expressions. The Flavor menu switches the engine that runs your pattern, the flags on offer, and the way a replacement refers to a group. JavaScript is built into your browser. Each of the others downloads once, when you first pick it.

FlavorEngineIn a replacementGood to know
JavaScriptYour browser's own regex engine$1 $<name> $&Gives the same results as JavaScript and TypeScript code in this browser.
PCRE2 (PHP)PCRE2, the engine behind PHP's preg functions, as WebAssembly$1 \1 $0UTF and Unicode properties are always on, as with PHP's u modifier. Replacements follow preg_replace, so groups are used by number. Groups are listed for each match but not underlined in the text.
PythonPython's own re module, run with Pyodide\1 \g<name> \g<0>The largest engine, about 6 MB the first time you pick it.
Go (RE2)RE2JS, a JavaScript port of the RE2 engine that Go's regexp package follows${1} ${name} ${0}No lookahead, lookbehind, or backreferences. Google Sheets regex formulas use RE2 as well.
RustThe Rust regex crate as WebAssembly${1} ${name} ${0}No lookahead, lookbehind, or backreferences.

The replacement column shows a numbered group, a named group, and the whole match. PHP has no way to use a group by name in a replacement, so it shows both ways to write a numbered group.

Regex cheat sheet

The building blocks you will use most, as they work in JavaScript. Most are the same in the other flavors. The exceptions are in the list of differences further down.

PatternWhat it matches
.Any character except a line break (any at all with the s flag)
\d \DA digit 0 to 9, or anything that is not a digit
\w \WA word character (A to Z, a to z, 0 to 9, _), or not
\s \SWhitespace (space, tab, line break), or not
\bA word boundary, the edge between a word and a non-word character
^ $Start and end of the text (of each line with the m flag)
[abc] [^abc]Any one of a, b, or c, or any character except those
[a-z]Any character in the range a to z
a|ba or b
* + ?0 or more, 1 or more, 0 or 1 of the item before
{3} {2,} {2,5}Exactly 3, at least 2, or 2 to 5 times
*? +? ??Lazy versions: match as little as possible
( )Capture group, numbered from 1
(?<name> )Named capture group
(?: )Group without capturing
\1 \k<name>Backreference: the same text a group matched earlier
(?= ) (?! )Lookahead: followed by, or not followed by
(?<= ) (?<! )Lookbehind: preceded by, or not preceded by
\p{L}A Unicode letter in any language (needs the u flag)
\. \* \(A backslash makes a special character literal

JavaScript regex flags

Flags go after the closing slash, as in /cat/gi, and change how the whole pattern behaves. The other flavors have their own flag buttons: x (extended, or verbose in Python) in PCRE2, Python, and Rust, U (ungreedy) in PCRE2, Go, and Rust, and a (ASCII) in Python. Outside JavaScript, g is a setting of this tester that picks every match or only the first. It is not part of the language.

FlagNameWhat it does
gglobalFind every match. Without it, only the first match is found and replaced.
iignore caseUpper and lower case letters match each other.
mmultiline^ and $ match at the start and end of every line, not just the whole text.
sdotAllThe dot (.) also matches line breaks.
uunicodeTreats the pattern as full Unicode, so emoji count as one character and \p{...} works. Also makes unneeded escapes an error.
ystickyEach match must start exactly where the last one ended, with no skipping ahead.

Common regex examples

Each of these is in the Examples menu above with sample text and a replacement to try, so you can load one and adjust it. They are shown here as JavaScript, and the menu rewrites each one for the flavor you picked. The repeated words pattern needs a backreference, so it is left out for Go and Rust. Patterns for emails and URLs are practical filters, not full validators of every address the standards allow.

FindsPattern
Email addresses/[\w.+-]+@[\w-]+(?:\.[\w-]+)+/g
URLs/https?:\/\/[^\s/$.?#][^\s]*/gi
US phone numbers/\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/g
Dates (YYYY-MM-DD)/(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])/g
IPv4 addresses/\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)\b/g
Hex colors/#(?:[0-9a-fA-F]{3}){1,2}\b/g
Repeated words/\b(\w+)\s+\1\b/gi
Trailing spaces/[ \t]+$/gm

How regex differs between JavaScript, Python, PHP, Go, and Rust

Most syntax works the same everywhere, but a pattern that works in one language can fail in another. These are the differences people run into most. Switch the flavor above to see each one for yourself.

  • ·Named groups. JavaScript writes (?<name>...). Python only accepts (?P<name>...), which is a syntax error in JavaScript. PCRE2, Go, and Rust accept both.
  • ·Replacements. JavaScript uses $1 and $<name>. Python uses \1 and \g<name>. PHP takes $1 or \1. Go and Rust use $1 or ${name}, and there the braces matter: $1x means a group named 1x, while ${1}x means group 1 followed by an x.
  • ·Lookaround and backreferences. Go and Rust have no lookahead, lookbehind, or backreferences such as\1. JavaScript, PCRE2, and Python have all three.
  • ·Anchors. The anchors \A and \Z from Python and PHP do not exist in JavaScript. Use ^ and $ without the m flag.
  • ·Flags in the pattern. A leading (?i) switches on a flag in PCRE2, Python, Go, and Rust. JavaScript does not accept it, so use the flag buttons instead.
  • ·PCRE extras. Possessive quantifiers like a++ and atomic groups like (?>...), which PCRE2 supports, are not part of JavaScript regex.
  • ·Google Sheets. REGEXMATCH, REGEXEXTRACT, and REGEXREPLACE use the RE2 engine, which has no lookahead, lookbehind, or backreferences. Pick the Go (RE2) flavor to test a pattern for those formulas.

Who uses a regex tester

  • ·Web and app developers. Build and debug patterns for form validation, routing, parsing logs, or splitting strings before putting them in JavaScript, Python, PHP, Go, or Rust code.
  • ·Data analysts. Work out a pattern to pull IDs, dates, or codes out of messy text before using it in a Python script or a spreadsheet formula.
  • ·Writers and editors. Plan a find-and-replace for an editor that supports regex, such as VS Code, and preview the result on a sample first.
  • ·Students. Learn how each part of a pattern behaves by changing it and watching the highlights move.

Regex tester FAQ

Which regex flavors does this tester support?
JavaScript, PCRE2 (the engine PHP uses), Python, Go (RE2 syntax), and Rust. Pick one from the Flavor menu. JavaScript runs on your browser's own engine. PCRE2 and Rust run as WebAssembly builds of the real engines, Python runs its own re module through Pyodide, and Go uses RE2JS, a JavaScript port of RE2. Java and .NET are not supported.
Can I test a Python or PHP regex here?
Yes. Pick Python or PCRE2 (PHP) in the Flavor menu and type the pattern without the quotes or delimiters your code needs, so the PHP pattern '/\d+/i' becomes \d+ with the i flag on. Python patterns run on Python's own re module, so (?P<name>...) groups and \1 replacements behave as they do in Python. The Python engine is about 6 MB and downloads the first time you pick it.
Why does my regex only find the first match?
Turn on the g (global) flag. Without it, the tester stops after the first match, and a replace only changes the first one.
Why doesn't the dot match a new line?
By default, . matches any character except line breaks. Turn on the s (dotAll) flag to make it match line breaks too, or use [\s\S] to match any character.
How do I match a literal dot, plus sign, or bracket?
Put a backslash before it. The characters . * + ? ^ $ { } ( ) [ ] | / and \ have special meanings, so \. matches a real period and \( matches a real opening bracket.
What is the difference between greedy and lazy matching?
Greedy quantifiers like .* take as much text as they can, so <.*> on "<a><b>" matches the whole string. Adding a question mark makes them lazy, so <.*?> matches "<a>" and then "<b>" separately.
How do I use capture groups in a replacement?
In the Replace tab, click a button under the box to insert a group, or type the code yourself. The code depends on the flavor: $1 and $<name> in JavaScript, $1 or \1 in PCRE2 (PHP), \1 and \g<name> in Python, and ${1} and ${name} in Go and Rust.
How do I delete every match instead of replacing it?
Open the Replace tab and leave the replacement box empty. Each match is removed from the result. Keep the g flag on, or only the first match is removed.
Why does lookahead or a backreference fail in Go or Rust?
The RE2 engine and the Rust regex crate leave out lookahead, lookbehind, and backreferences such as \1 on purpose. Without them, the time a match takes always grows in step with the length of the text. The tester shows the engine's error when a pattern uses one. Rewrite the pattern without it, or check the surrounding text in your code.
Why was my pattern stopped for taking too long?
Some patterns, often ones with a repeat inside a repeat like (a+)+ or (.*)*, try an enormous number of ways to match before failing. This is called catastrophic backtracking. The tester runs your pattern in the background and stops it after a moment so the page does not freeze. Rewrite the pattern so each part can only match text one way.
Does JavaScript support lookbehind?
Yes. (?<=...) and (?<!...) work in all current browsers and in Node.js. Unlike Python, JavaScript lookbehinds can be any length.
Is my text sent anywhere?
No. The pattern and the test text are processed in your browser, and nothing is uploaded or saved.