Regex Tester
Test JavaScript regular expressions with live highlighting of all matches, capture group details and positions. Supports gimsuy flags and named groups. Runs locally.
The regex tester checks whether an expression matches as intended: enter the pattern, the flags and the test text, and matches are highlighted live while each match's position and capture groups are listed. It suits validating a rule — an email pattern, a phone number, a URL, a log parser — before it goes into code, so that over-matching or under-matching is caught before release rather than after.
Expressions run as JavaScript RegExp, the flags combine from g, i, m, s, u and y, and the scan is always global internally so that every match is listed. Dialects differ, though: PHP PCRE, Python re and JavaScript do not agree on named-group syntax ((?<name>…) against (?P<name>…)) or on lookbehind support, so a pattern being ported needs checking clause by clause.
Did this tool solve your problem?
Submitting sends the tool name, your input and the current result to the server. Please do not include ID numbers, phone numbers or other private data.
AI assistant It answers using your current input and result
Asking again sends your current input and result to the server once more. Please do not include private data.
How to use
- Enter the pattern and the flags.
- Paste the test text and read the live highlights.
- Check the match positions and capture groups.
- Verify dialect differences before porting to another language.
How it works
Three inputs, live matching
Fill the three boxes: the regex, the flags (optional, defaults to g) and the test text. Any change re-matches instantly — no button to press. Regexes follow JavaScript RegExp syntax, like \d{4}-\d{2}-\d{2}.
Flags and how they combine
Flags combine freely: g global, i case-insensitive, m multiline, s dot matches newline, u Unicode, y sticky. The tool always scans globally to list every match; single-match semantics are unaffected.
Reading the match details
The result area highlights matched fragments in original order; the detail table lists each match's content, start position and capture groups ($1, $2...), with named groups listed by number too. Optional groups that didn't participate are marked as unmatched.
Code example
JavaScript Extracting all matches and capture groups
// Global match and iterate
const re = /(\d{4})-(\d{2})-(\d{2})/g;
for (const m of "dates 2026-09-14 and 2026-10-01".matchAll(re)) {
console.log(m[0], m[1], m[2], m[3]); // 2026-09-14 2026 09 14
}
// Named groups
const named = /(?<y>\d{4})-(?<m>\d{2})/.exec("2026-09");
named.groups.y; // "2026"
Shell Validating and extracting on the command line
# Validate an email format with grep -E
printf "a@b.com\nnot-an-email\n" | grep -E "^[^@]+@[^@]+\.[a-z]{2,}$"
# Extract and rewrite a date with sed (note the dialect differences between implementations)
echo "2026-09-14" | sed -E "s/([0-9]{4})-([0-9]{2})-([0-9]{2})/\2\/\3\/\1/"
FAQ
What do the gimsuy flags mean?
g finds all matches instead of the first; i ignores case; m makes ^ $ match line starts and ends; s lets . match newlines; u enables full Unicode matching (surrogate pairs); y is sticky (matches only from lastIndex). Combine freely, like gi.
How do I see capture groups and named groups?
Parenthesized parts are capture groups, numbered by opening parenthesis ($1, $2...); (?<name>...) names them. The detail table lists each match's group values by number; null means the group didn't participate (an untaken optional branch).
Why does my regex report a syntax error?
Common causes: unbalanced parentheses or brackets, a quantifier with nothing before it (*abc), or incomplete escaping (a literal dot needs \. not .). The tool uses the browser's native RegExp engine, so an error means the syntax really is invalid — comment out sections to isolate it.
Is the test text uploaded?
No. Matching runs on the browser's native RegExp; neither text nor regex crosses a server, and it works offline. Logs and API responses with sensitive content are safe to paste.
Greedy vs. lazy matching?
Quantifiers are greedy by default, eating as much as possible: <.+> swallows the whole <a><b>. Add ? for lazy matching: <.+?> stops at the first >. For HTML and quoted content prefer lazy matching, or exclusion sets like [^>] for precision.
What is a zero-width match?
A match whose content is the empty string: a* succeeds even where there's no a, matching an empty string in empty text. Such matches would stall forever at the same position, so the tool forces one-step progress on them. In practice a* on empty text yields 1 empty match (position 0) and on bbb yields 4 (positions 0-3).
Are backreferences and lookarounds supported?
Yes. \1 references the first capture group; lookarounds (?=...) (?!...) (?<=...) (?<!...) all work in modern browsers, and named backreferences are \k<name>. Everything executes on the native engine — identical to new RegExp in the console.