X Xerobit

Regex Tester Online — Test Regular Expressions with Live Match Highlighting

A regex tester shows which parts of your test string match your pattern in real time. Here's how to use one effectively, what flags do, and how to debug patterns that aren't...

Mian Ali Khalid · · 6 min read
Use the tool
Regex Tester
Test regular expressions with live match highlighting and explanation.
Open Regex Tester →

A regex tester runs your regular expression against test text in real time, highlighting matches as you type. It’s the fastest way to verify a pattern works — faster than running code, faster than reading documentation.

Use the Regex Tester for live match highlighting, capture group inspection, and flag toggles.

How to use a regex tester effectively

Write the test string first

Before writing the regex, paste 5–10 representative test cases in the input:

  • Examples that should match
  • Examples that should NOT match (equally important)
  • Edge cases: empty strings, special characters, unusual formats

A regex that matches your examples may fail on edge cases. Having the edge cases in your test string catches this immediately.

Build the pattern incrementally

Don’t write the full pattern at once. Start simple and add complexity:

Goal: match email addresses

Step 1: [\w.+%-]+  (match the local part)
Step 2: [\w.+%-]+@  (add the @)
Step 3: [\w.+%-]+@[\w-]+  (add domain)
Step 4: [\w.+%-]+@[\w-]+\.[\w.]+  (add TLD)

Each step, verify the partial pattern against your test string. This catches errors earlier and is easier to debug than a 60-character pattern that doesn’t work.

Check non-matches explicitly

A common mistake is a regex that matches too broadly. Test with strings that shouldn’t match:

  • For email: not-an-email, @missing-local.com, double@@at.com
  • For dates: 99/99/9999, 13/01/2024 (month 13 is invalid)
  • For phone numbers: 123-456 (too short), 1234-567-8901 (wrong format)

Regex flags explained

Flags change how the pattern is applied:

FlagNameEffect
gGlobalFind all matches (without: stop at first)
iCase-insensitiveA matches a
mMultiline^ and $ match line boundaries, not string start/end
sDotAll. matches newlines (without: . skips \n)
uUnicodeEnable full Unicode matching
xExtendedAllow whitespace and comments in pattern (not all engines)

Most commonly needed:

  • g — almost always needed for “find all occurrences”
  • i — for case-insensitive matching (URLs, emails, names)
  • m — when your text has multiple lines and you want ^/$ to match each line
  • s — when matching content that spans multiple lines
// Without 'm' flag — ^ and $ match start/end of entire string:
'line1\nline2'.match(/^line\d$/g);    // null

// With 'm' flag — ^ and $ match each line:
'line1\nline2'.match(/^line\d$/gm);  // ['line1', 'line2']

Common debugging patterns

”My pattern doesn’t match anything”

  1. Check for unescaped special characters. In regex, ., *, +, ?, (, ), [, ], {, }, ^, $, |, \ have special meanings. To match them literally, escape with \.

    Pattern 3.14 matches 3X14 (. = any char). Pattern 3\.14 matches only 3.14.

  2. Check the anchor positions. ^error$ only matches the string "error" with nothing else. If you want to find “error” anywhere in a string, use just error without anchors.

  3. Check the flag. Without g, only the first match is returned. Without i, case must match exactly.

”My pattern matches too much”

  1. Use anchors (^, $) to constrain where the match can start/end.

  2. Use word boundaries (\b). \bcat\b matches “cat” but not “catch” or “concatenate”. Without \b, cat matches inside any word containing those letters.

  3. Make quantifiers lazy. .* is greedy — it matches as much as possible. .*? is lazy — it matches as little as possible.

    String: <b>bold</b> and <i>italic</i>
    Pattern <.*>:  matches '<b>bold</b> and <i>italic</i>' (everything)
    Pattern <.*?>: matches '<b>', '</b>', '<i>', '</i>' (each tag separately)
  4. Use character classes instead of . for targeted matching. Instead of .*, use [^"]* to match anything except a quote character.

”My capture groups aren’t working”

Groups in parentheses (...) capture what they match. Name them for clarity: (?<year>\d{4}).

// Named capture groups:
const date = '2024-05-11';
const match = date.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
console.log(match.groups); // { year: '2024', month: '05', day: '11' }

// Non-capturing group (?: ) — group without capture:
'foobar'.match(/(?:foo)(bar)/)[1]; // 'bar' — only (bar) is captured

Regex syntax quick reference

.       Any character except newline
\d      Digit [0-9]
\D      Non-digit
\w      Word character [a-zA-Z0-9_]
\W      Non-word character
\s      Whitespace (space, tab, newline)
\S      Non-whitespace
\b      Word boundary
^       Start of string (or line with m flag)
$       End of string (or line with m flag)
[abc]   Any of: a, b, c
[^abc]  Not any of: a, b, c
[a-z]   Range: a through z
(...)   Capture group
(?:...) Non-capturing group
a|b     a or b
a?      0 or 1 of a (optional)
a*      0 or more of a
a+      1 or more of a
a{3}    Exactly 3 of a
a{3,5}  3 to 5 of a
a{3,}   3 or more of a

Testing in your target language

Regular expression syntax varies slightly across languages and engines. The Regex Tester uses JavaScript’s regex engine. If you’re writing a pattern for Python or PHP:

  • Python doesn’t support \d+? non-greedy in the same way (it does in re.search but the syntax is standard)
  • Python uses (?P<name>...) for named groups instead of (?<name>...)
  • PHP uses PCRE (similar to Perl) — syntax is close but not identical to JavaScript

Always test in the target runtime if the pattern is going into production code.


Related posts

Related tool

Regex Tester

Test regular expressions with live match highlighting and explanation.

Written by Mian Ali Khalid. Part of the Dev Productivity pillar.