Regex Tester
| # | Index | Match | Groups |
|---|---|---|---|
| 1 | 6 | 42 | — |
| 2 | 15 | 7 | — |
Common Patterns
How it works
Type a regular expression at the top, type or paste the text you want to test below, and the tool highlights every match in real time. Each match shows in a coloured pill on the test string, and a results table beneath lists the matched substring, its character index, its length, and any capture groups (positional and named). Patterns are compiled with the browser's native `RegExp` engine, so what you see here is exactly what your JavaScript / Node / Deno code will see in production.
A regular expression is a compact mini-language for describing text patterns. The core building blocks you reuse all the time:
• `.` matches any character except newline • `\d` matches a digit (0–9), `\D` a non-digit • `\w` matches a word character (letters, digits, underscore), `\W` a non-word character • `\s` matches whitespace (space, tab, newline), `\S` non-whitespace • `[abc]` matches any of a, b, c. `[a-z]` is a range. `[^abc]` negates the set • `+` is one or more. `*` is zero or more. `?` is zero or one. `{3}` exactly 3. `{2,5}` 2 to 5. `{2,}` 2 or more • `^` is start of line/string. `$` is end of line/string • `\b` is a word boundary. `\B` a non-boundary • `(...)` is a capture group. `(?:...)` a non-capturing group. `(?<name>...)` a named group • `(?=...)` is lookahead. `(?!...)` negative lookahead. `(?<=...)` lookbehind. `(?<!...)` negative lookbehind • `|` is alternation (or)
The flags (the letters after the closing `/`) change how the whole pattern behaves: `g` finds every match instead of just the first, `i` ignores case (A = a), `m` makes `^` and `$` match each line's start/end instead of just the whole string, `s` makes `.` also match newlines, `u` enables full Unicode (essential for emoji and non-Latin characters), `y` matches sticky at the lastIndex position only.
The trap to know about: catastrophic backtracking. Patterns with nested quantifiers like `(a+)+$` against a long string that almost matches can take minutes to fail, because the engine tries every possible split. The fix is to avoid nesting, use atomic groups where available, or rewrite the pattern (`a+$` works fine). If your browser tab freezes when you paste a pattern, this is almost always why.
The tool is fully client-side: the pattern and the test string are compiled and executed in your browser's RegExp engine. Nothing leaves your device, which matters because regex testing usually involves real email addresses, auth tokens, log excerpts, or PII you would not want to send to a server.
Frequently Asked Questions
What is a regular expression?
- A pattern that describes a set of strings. Common building blocks: . (any character), \d (digit), \w (word character), + (one or more), * (zero or more), ^ (start of line), $ (end of line), [] (character set), () (capture group). Example: \d{2}/\d{2}/\d{4} matches dates like 25/12/2025.
What regex syntax does this tester support?
- All standard JavaScript regex syntax, because the tool uses the browser's built-in RegExp engine. That includes lookahead, lookbehind, named groups, and Unicode property escapes.
What do the regex flags g, i, m, s, u and y mean?
- g = global (find all matches, not just the first), i = case-insensitive (A matches a), m = multiline (^ and $ match the start and end of each line, not just of the whole text), s = dotAll (. also matches newlines), u = Unicode (full Unicode support), y = sticky (match from the exact position only).
Why doesn't my regex match across multiple lines?
- Enable the m (multiline) flag if your pattern uses the ^ or $ anchors, so they match the start and end of each line rather than of the entire text. And note that . does not match newlines by default: turn on the s (dotAll) flag if you want it to.
Why is my browser tab freezing on a specific regex pattern?
- You are almost certainly hitting catastrophic backtracking. Patterns like (a+)+$ or (.*)*$ against a string that almost matches explode exponentially as the engine tries every possible split. The fix is to make the inner quantifier atomic, use possessive quantifiers where your engine has them, or rewrite the pattern without nested quantifiers.
How do I use capture groups in regex?
- Wrap the part you want to keep in parentheses, which creates a numbered group. (\d{4})-(\d{2})-(\d{2}) against "2026-04-18" captures "2026", "04" and "18" as groups 1, 2 and 3. You can also name a group with (?<year>\d{4}) and reference it by name in replacements or code, and use (?:...) when you need to group without capturing.
Is my text sent anywhere?
- No. The pattern is compiled and executed locally using the browser's native RegExp engine. Nothing about your pattern or the test string leaves your device, which matters because people often test patterns against real email addresses, auth tokens, or log excerpts.
Common regex patterns: copy-paste cheat sheet
Battle-tested patterns for the things developers match most often. All patterns are JavaScript-compatible (use as-is in `new RegExp(...)` or `/.../flags`). Add the `i` flag where case-insensitive matching is desired.
| Match | Pattern | Example matches | Notes |
|---|---|---|---|
| Email (pragmatic) | ^[^\s@]+@[^\s@]+\.[^\s@]+$ | alice@example.com, bob+tag@a.co | Not RFC-5322-strict but accepts ~99% of real addresses without false negatives. The full RFC pattern is 6,000 characters and rejects valid emails. Pragmatic beats correct here |
| URL (http/https) | https?:\/\/[\w\-]+(\.[\w\-]+)+[\/\w\-\.~:?#\[\]@!$&'()*+,;=%]* | https://example.com/path?q=1 | Matches most http(s) URLs. For deep parsing prefer the URL API (`new URL(s)`) |
| IPv4 address | \b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b | 192.168.1.1, 10.0.0.255 | Validates each octet ≤ 255. For just "4 dotted numbers" use `\b\d{1,3}(\.\d{1,3}){3}\b` |
| IPv6 (loose) | \b(?:[A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}\b | 2001:db8::1, ::1 (with compression) | Strict IPv6 with all forms is ~150 chars; this pragmatic form catches the full-uncompressed case |
| Italian fiscal code (CF) | ^[A-Z]{6}\d{2}[A-EHLMPRST]\d{2}[A-Z]\d{3}[A-Z]$ | RSSMRA80A01H501Z | Basic structural check, not checksum. 16 chars, uppercase |
| EU VAT number (generic) | ^[A-Z]{2}[A-Z0-9]{2,12}$ | IT12345678901, DE123456789 | Structural only. For real validation use the VIES web service |
| UUID v4 | ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ | f47ac10b-58cc-4372-a567-0e02b2c3d479 | Use `i` flag for uppercase. The `4` and `[89ab]` enforce v4 spec |
| Hex colour (#abc / #aabbcc) | ^#(?:[\dA-Fa-f]{3}|[\dA-Fa-f]{6}|[\dA-Fa-f]{8})$ | #fff, #1A73E8, #80ffffff | Accepts 3-digit, 6-digit and 8-digit (with alpha) |
| ISO date (YYYY-MM-DD) | ^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$ | 2026-04-18, 2026-12-31 | Structural: doesn't validate Feb 30. Pair with `Date.parse()` for full validation |
| ISO datetime (with Z) | ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?$ | 2026-04-18T14:32:00Z | ISO 8601 with optional milliseconds and Z timezone |
| 24-hour time HH:MM | ^([01]\d|2[0-3]):[0-5]\d$ | 09:30, 23:59 | Add `:[0-5]\d` at the end for HH:MM:SS |
| Strong password (8+, mixed) | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$ | P@ssw0rd, MyT@xes1 | Lookaheads enforce ≥1 lowercase, uppercase, digit, special. Modern guidance prefers length over composition |
| Slug (URL-safe) | ^[a-z0-9]+(?:-[a-z0-9]+)*$ | my-blog-post, hello | Lowercase letters, digits, hyphens. No leading/trailing/consecutive hyphens |
| Whitespace-only line | ^\s*$ | (empty), (spaces only) | With `m` flag, matches every blank line in a multiline string |
| Trim leading/trailing whitespace | ^\s+|\s+$ | hello | Use with `.replace(/^\s+|\s+$/g, '')`, equivalent to `String.trim()` |
| Phone (international, loose) | ^\+?[1-9]\d{1,14}$ | +393331234567, 14155551212 | E.164 format. Country code optional. For per-country strict validation use libphonenumber |
| Credit-card digits only (loose) | ^\d{13,19}$ | 4111111111111111 | Length check only. Use Luhn algorithm for actual validation |
| Markdown link | \[([^\]]+)\]\(([^)]+)\) | [Click](https://x.com) | Captures group 1 = text, group 2 = URL. Doesn't handle nested brackets: limitation, not bug |
| HTML tag (loose) | <\/?[a-z][\w-]*(?:\s+[\w-]+(?:="[^"]*"|='[^']*'|=\S+)?)*\s*\/?> | <a href="x"> | Don't use regex to parse arbitrary HTML. For production parsing use DOMParser. This is fine for log scraping |
Patterns are JavaScript-compatible (ECMAScript 2018+ regex). Tested against the JavaScript native `RegExp` engine. PCRE/Python/Java implementations may differ in edge cases (especially lookbehind support and Unicode properties).