Privatool
Guide6 min read

Regex Tester Online Free — Test and Debug Regular Expressions

Test regular expressions against sample text in real time. See matches highlighted, group captures, and get explanations. No signup needed.

By Privatool Team·

A regular expression (regex) is a sequence of characters that defines a search pattern. Regex is used in almost every programming language for searching, validating, and transforming text. Testing regex interactively — before embedding it in code — prevents bugs that are notoriously hard to debug later.

Regex basics

Pattern Matches
. Any single character
\d Any digit (0–9)
\w Word character (a-z, A-Z, 0-9, _)
\s Whitespace (space, tab, newline)
^ Start of line
$ End of line
* 0 or more of preceding
+ 1 or more of preceding
? 0 or 1 of preceding
{n,m} Between n and m of preceding
[abc] Any of a, b, or c
[^abc] Not a, b, or c
(abc) Capture group
a|b a or b

Common regex flags

  • g — Global: find all matches, not just the first
  • i — Case insensitive: [a-z] also matches [A-Z]
  • m — Multiline: ^ and $ match start/end of each line
  • s — Dotall: . matches newline characters too

Useful regex patterns

Email validation:

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

URL matching:

https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}

Phone number (flexible):

[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}

Date (YYYY-MM-DD):

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

IPv4 address:

^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$

How to test regex online

  1. Go to Regex Tester
  2. Enter your regular expression in the pattern field
  3. Set flags (g, i, m) as needed
  4. Paste or type test text in the input area
  5. Matches are highlighted instantly; capture groups shown below

Regex pitfalls to avoid

  • Catastrophic backtracking — nested quantifiers like (a+)+ can freeze on long inputs; test with worst-case strings
  • Anchors — forgetting ^ and $ lets partial matches pass validation
  • Greedy vs lazy.* is greedy (takes as much as possible); .*? is lazy (takes as little as possible)

Catastrophic backtracking, concretely

This is the pitfall most likely to take down a production service, so it is worth seeing in action. The pattern ^(a+)+$ looks harmless:

Input: aaaaaaaaaaaaaaaaaaaaaaaaX     (24 a's, then a non-match)

Because a+ can be split among the repetitions in exponentially many ways, the engine tries roughly 2^24 combinations before concluding there is no match. Add one more a and the time doubles. This is the mechanism behind ReDoS (Regular Expression Denial of Service) — a single crafted input pins a CPU core.

The warning sign is a quantifier applied to a group that already contains a quantifier, where the inner parts can match the same text: (a+)+, (a*)*, (\d+|\w+)*.

Fixes:

  • Make the inner pattern exact: ^a+$ matches the same strings with no ambiguity.
  • Use an atomic group or possessive quantifier if your engine has them(?>a+)+ works in PCRE (PHP, Perl) and .NET, but not in JavaScript: native RegExp throws Invalid group on it, and that is the engine this site's tester uses. In JS, rewrite the pattern instead.
  • Bound the input length before matching.
  • Never run a user-supplied regex against a user-supplied string on a server.

Greedy vs lazy, shown

The difference is easiest to see on HTML-ish text:

Text:    <b>bold</b> and <i>italic</i>
Greedy:  <.+>    -> matches the ENTIRE string
Lazy:    <.+?>   -> matches <b>, then </b>, then <i>, then </i>

Greedy takes everything to the last >, then backs off until the pattern fits. Lazy takes the minimum and expands only as needed. When a pattern "matches too much", greediness is usually why.

Why email regex is a trap

The email pattern above is fine for a signup form, but it is not RFC-correct — the actual grammar allows quoted strings, comments, and IP-literal domains, and a fully compliant expression runs to thousands of characters. Meanwhile the pattern above rejects valid addresses containing + in some variants and accepts plenty of addresses that do not exist.

The reliable check is: pattern-match loosely to catch typos, then send a confirmation email. That is the only test that proves an address is real.

Escaping user input

If any part of a pattern comes from user input, escape it. Otherwise a stray ( throws a syntax error and a .* changes the meaning:

const escape = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
const re = new RegExp(escape(userInput), 'i')

The g flag and lastIndex

A regex with g is stateful. Reusing the same object across calls to .test() produces alternating true/false results, because lastIndex advances between calls:

const re = /a/g
re.test('a')  // true
re.test('a')  // false  <- same input, different answer

Create the regex inside the loop, or reset re.lastIndex = 0, or drop g when you only need a boolean.

Frequently asked questions

Is regex the same in every language?

No. The core syntax is shared, but lookbehind, named groups, and Unicode handling vary. JavaScript, PCRE (PHP/Perl), Python re, and Go's RE2 all differ. RE2 notably has no backtracking at all, so it cannot suffer ReDoS but also does not support lookaround.

When should I not use regex?

For nested structures — HTML, JSON, source code. Regular expressions cannot count arbitrary nesting depth, so a pattern that appears to work will fail on the first deeply nested input. Use a real parser instead.

Why does my pattern work here but fail in code?

Usually double-escaping. In a string literal, \d must be written "\\d". Using a regex literal (/\d/) or a raw string (r"\d" in Python) avoids the problem.

How do I match across multiple lines?

Two different flags: m makes ^ and $ match at each line break, while s makes . match a newline. They are independent and often both needed.

What are named capture groups?

(?<year>\d{4}) lets you read the match as match.groups.year instead of match[1], which keeps patterns readable when group order changes.

Test your regex free →

Share this article
#regex tester#regular expression tester#test regex online#regex validator#regex debugger

Try our free tools

All tools run in your browser. Files never leave your device.

Explore free tools →