How to test regular expressions online
jsonsql.dev lets you test regex patterns instantly in your browser. No data is sent to any server — your text stays on your machine.
Enter your regex pattern — type your regular expression in the pattern input field. Select flags like global (g), case-insensitive (i), multiline (m), dotAll (s), or unicode (u).
Type or paste your test string — enter the text you want to match against. All matches highlight instantly as you type.
Review matches and groups — see total match count, each match with its index and length, plus all capture groups (numbered and named).
Example
Pattern: (\d{4})-(\d{2})-(\d{2}) with flag g
Test string:
Meeting on 2026-04-07 and follow-up on 2026-05-15.Result:
Match 1: "2026-04-07" at index 11, length 10
Group 1: "2026"
Group 2: "04"
Group 3: "07"
Match 2: "2026-05-15" at index 39, length 10
Group 1: "2026"
Group 2: "05"
Group 3: "15"Features
- Live matching as you type — both regex and test string update results instantly
- Flag toggles: global (g), case-insensitive (i), multiline (m), dotAll (s), unicode (u)
- Color-coded match highlighting directly in the test string
- Detailed match info: full text, index position, length for every match
- Capture groups displayed for each match — both numbered and named groups
- Quick-insert common patterns: email, URL, IP address, phone, date, hex color
- Basic pattern explanation showing what the regex does
- Replace mode with support for backreferences ($1, $2, $&)
- Dark and light theme support
- Works offline — no internet needed after the page loads
- 100% client-side — no data leaves your browser
Regex Tester vs other tools
| Feature | jsonsql.dev | regex101.com | regexr.com |
|---|---|---|---|
| Live highlighting | Yes | Yes | Yes |
| 100% client-side | Yes | No (server) | Yes |
| No account required | Yes | Optional | Optional |
| Capture groups | Yes | Yes | Yes |
| Named groups | Yes | Yes | Yes |
| Replace mode | Yes | Yes | Yes |
| Quick patterns | Yes | No | Partial |
| No ads | Yes | Has ads | No ads |
| Dark mode | Yes | Yes | No |
| Works offline | Yes | No | No |
| Multi-language support | JavaScript | Multiple (PHP, Python, Go, etc.) | JavaScript |
Regular expression syntax reference
Regular expressions are patterns used to match character combinations in strings. A single regex can replace dozens of lines of string-parsing code.
Character classes
| Syntax | Meaning | Example |
|---|---|---|
. | Any character except newline | a.c matches "abc", "a1c", "a-c" |
\d | Any digit (0-9) | \d{3} matches "123", "456" |
\w | Any word character (a-z, A-Z, 0-9, _) | \w+ matches "hello", "var_1" |
\s | Any whitespace (space, tab, newline) | \s+ matches " ", "\t\n" |
[abc] | Any one of the listed characters | [aeiou] matches any vowel |
[^abc] | Any character NOT listed | [^0-9] matches any non-digit |
[a-z] | Any character in the range | [A-Za-z] matches any letter |
Anchors
| Syntax | Meaning | Example |
|---|---|---|
^ | Start of string (or line with m flag) | ^Hello matches "Hello" at start |
$ | End of string (or line with m flag) | world$ matches "world" at end |
\b | Word boundary | \bcat\b matches "cat" but not "catch" |
Quantifiers
| Syntax | Meaning | Example |
|---|---|---|
* | 0 or more (greedy) | ab*c matches "ac", "abc", "abbc" |
+ | 1 or more (greedy) | ab+c matches "abc", "abbc" but not "ac" |
? | 0 or 1 (optional) | colou?r matches "color" and "colour" |
{n} | Exactly n times | \d{4} matches exactly 4 digits |
{n,m} | Between n and m times | \d{2,4} matches 2 to 4 digits |
*?, +? | Lazy (non-greedy) versions | <.+?> matches shortest tag |
Groups and references
| Syntax | Meaning | Example |
|---|---|---|
(...) | Capturing group | (\d{4})-(\d{2}) captures year and month |
(?:...) | Non-capturing group | (?:ab)+ matches "abab" without capturing |
(?<name>...) | Named capturing group | (?<year>\d{4}) captures as "year" |
Lookahead and lookbehind
| Syntax | Meaning | Example |
|---|---|---|
(?=...) | Positive lookahead | \d+(?= USD) matches "100" in "100 USD" |
(?!...) | Negative lookahead | \d+(?! USD) matches "100" in "100 EUR" |
(?<=...) | Positive lookbehind | (?<=\$)\d+ matches "50" in "$50" |
(?<!...) | Negative lookbehind | (?<!\$)\d+ matches "50" in "EUR 50" |
Flags
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not just the first |
i | Case-insensitive | Ignore upper/lower case differences |
m | Multiline | ^ and $ match line boundaries |
s | DotAll | . also matches newline characters |
u | Unicode | Proper Unicode code point matching |
Common regex patterns
Here are practical regex patterns you can use right away. Click any "Quick patterns" button above to load them into the tester instantly.
| Pattern | Regex | Example matches |
|---|---|---|
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ | user@example.com, name+tag@domain.org | |
| URL | https?:\/\/[^\s/$.?#].[^\s]* | https://example.com/path, http://localhost:3000 |
| IPv4 address | \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b | 192.168.1.1, 10.0.0.255 |
| Phone (international) | \+?[\d\s-]{10,} | +1 555-123-4567, 0123 456 7890 |
| Phone (US) | \(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4} | (555) 123-4567, 555.123.4567 |
| Date (YYYY-MM-DD) | \d{4}-\d{2}-\d{2} | 2026-04-07, 1999-12-31 |
| Hex color | #[0-9a-fA-F]{3,8} | #fff, #c2255c, #ff000080 |
| Password strength | (?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,} | Abc12345, P@ssw0rd123 |
| HTML tag | <([a-z]+)([^>]*)>(.*?)<\/\1> | <div class="x">text</div> |
| Username | ^[a-zA-Z0-9_-]{3,16}$ | john_doe, user-123 |
| ZIP code (US) | \b\d{5}(-\d{4})?\b | 90210, 10001-1234 |
| Credit card | \b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b | 4111-1111-1111-1111 |
Regex flags explained
Flags modify how the regex engine interprets your pattern. Understanding flags is essential for getting the matches you expect.
g (global) — find all matches
Without the g flag, the regex stops after the first match. With g, it finds every match in the string.
Pattern: \d+
Text: "I have 3 cats and 12 dogs"
Without g flag: Match 1: "3"
With g flag: Match 1: "3", Match 2: "12"i (case-insensitive) — ignore case
Makes the pattern match regardless of letter case.
Pattern: hello (with i flag)
Text: "Hello HELLO hello"
Matches: "Hello", "HELLO", "hello"m (multiline) — line-by-line anchors
With the m flag, ^ matches the start of each line and $ matches the end of each line, not just the start/end of the entire string.
Pattern: ^\w+ (with m flag)
Text:
"first line
second line
third line"
Matches: "first", "second", "third"s (dotAll) — dot matches newlines
By default, . matches any character except newlines. The s flag makes . match newline characters too.
Pattern: start.+end (with s flag)
Text: "start\nmiddle\nend"
Match: "start\nmiddle\nend" (entire text)u (unicode) — full Unicode support
Enables proper matching of Unicode code points, including emoji and characters outside the Basic Multilingual Plane.
Pattern: \p{Emoji} (with u flag)
Text: "Hello 🌍 World 🎉"
Matches: "🌍", "🎉"Regex capture groups and backreferences
Capture groups let you extract specific parts of a match. They are one of the most powerful features of regular expressions.
Numbered groups
Parentheses (...) create numbered capture groups, starting at $1.
Pattern: (\w+)@(\w+)\.(\w+)
Text: "user@example.com"
Full match: "user@example.com"
$1: "user"
$2: "example"
$3: "com"Named groups
Use (?<name>...) to give groups meaningful names instead of numbers.
Pattern: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
Text: "2026-04-07"
$<year>: "2026"
$<month>: "04"
$<day>: "07"Non-capturing groups
Use (?:...) when you need grouping for quantifiers or alternation but don't need to capture the result.
Pattern: (?:https?|ftp)://(\S+)
Text: "https://example.com"
$1: "example.com" (only the domain is captured)Backreferences in replace
In replacement strings, use $1, $2 (or $<name> for named groups) to insert captured values. Use $& for the full match.
// Reformatting dates from MM/DD/YYYY to YYYY-MM-DD
Pattern: (\d{2})\/(\d{2})\/(\d{4})
Replace: $3-$1-$2
Input: "04/07/2026"
Output: "2026-04-07"Regex in different programming languages
While this tool uses JavaScript's regex engine, regex syntax is similar across most languages. Here's how to use regex in popular languages.
JavaScript
// Literal syntax
const re = /\d{4}-\d{2}-\d{2}/g;
// Constructor syntax
const re2 = new RegExp('\\d{4}-\\d{2}-\\d{2}', 'g');
// Find matches
const matches = str.match(re); // ["2026-04-07"]
const allMatches = [...str.matchAll(re)]; // iterator with groups
// Replace
const result = str.replace(re, 'DATE');
// Test if pattern matches
const isValid = re.test(str); // true or falsePython
import re
# Find all matches
matches = re.findall(r'\d{4}-\d{2}-\d{2}', text)
# Find with groups
for m in re.finditer(r'(\d{4})-(\d{2})-(\d{2})', text):
print(m.group(1), m.group(2), m.group(3))
# Replace
result = re.sub(r'\d{4}', 'YYYY', text)
# Compile for reuse
pattern = re.compile(r'\d{4}-\d{2}-\d{2}')
pattern.findall(text)Go
import "regexp"
// Compile pattern (panics on invalid regex)
re := regexp.MustCompile(`\d{4}-\d{2}-\d{2}`)
// Find matches
match := re.FindString(text) // first match
allMatches := re.FindAllString(text, -1) // all matches
// Replace
result := re.ReplaceAllString(text, "DATE")
// Test
isMatch := re.MatchString(text)Command line (grep and sed)
# Find lines matching pattern (extended regex)
grep -E '\d{4}-\d{2}-\d{2}' file.txt
# Find and replace in-place with sed
sed -i 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/DATE/g' file.txt
# Count matches
grep -cE '\d{4}-\d{2}-\d{2}' file.txt
# Show only matching parts
grep -oE '\d{4}-\d{2}-\d{2}' file.txtRelated tools
Frequently asked questions
What is a capture group in regex?
A capture group is created by enclosing part of a pattern in parentheses (...). It captures the matched text so you can reference it later — in replacement strings as $1, $2, etc., or in code as match groups. Named capture groups use the syntax (?<name>...) and can be referenced as $<name>.
What is a lookahead in regex?
A lookahead checks if a pattern is followed (or not followed) by another pattern without including it in the match. Positive lookahead (?=...) asserts what follows must match. Negative lookahead (?!...) asserts what follows must NOT match. For example, \d+(?= USD) matches "100" in "100 USD" but not in "100 EUR".
Why is my regex matching too much (greedy vs lazy)?
By default, quantifiers like * and + are greedy — they match as much text as possible. To make them lazy (match as little as possible), add a ? after them. For example, <.+> applied to "<b>text</b>" matches the entire string (greedy), but <.+?> matches "<b>" and "</b>" separately (lazy).
What regex flags are supported?
Five flags are supported: g (global — find all matches), i (case-insensitive), m (multiline — ^ and $ match line boundaries), s (dotAll — dot matches newlines), and u (unicode — enable full Unicode matching).
Does the regex tester support lookahead and lookbehind?
Yes. This tool uses your browser's native JavaScript regex engine, which supports positive and negative lookahead (?=...) (?!...) and lookbehind (?<=...) (?<!...) in modern browsers.
What regex flavor does this tool use?
This tool uses JavaScript's native RegExp engine (ECMAScript flavor). It supports all modern features including named groups, lookbehind assertions, Unicode property escapes (with the u flag), and the dotAll (s) flag.