Regex Tester & Debugger→Specialized Version
šŸ”

MAC Address Regex Tester

Test and explain the mac address tester pattern

//gm
Flags:
Examples:
00:1B:44:11:3A:B7 00-1b-44-11-3a-b7 001B44113AB7 00:1B:44:11:3A
#MatchIndexGroups
100:1B:44:11:3A:B70—
200-1b-44-11-3a-b718—

The Pattern

``regex ^(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}$ `

Flags: gm — multiline, so ^ and $ anchor to each line rather than the whole input.

What It Accepts and Rejects

InputResult
00:1B:44:11:3A:B7āœ… matches
00-1b-44-11-3a-b7āœ… matches
001B44113AB7āŒ rejected
00:1B:44:11:3AāŒ rejected

Six Octets, One Separator Style

The pattern repeats "two hex digits and a separator" five times and then requires a final pair. That structure is what rejects a five-octet address, and the character class [:-] accepts both the colon notation Unix tools use and the hyphen notation Windows prefers.

Because the separator class is evaluated independently each time, 00:1B-44:11-3A:B7 is also accepted. Requiring a consistent separator needs a backreference: ^([0-9A-Fa-f]{2})([:-])(?:[0-9A-Fa-f]{2}\2){4}[0-9A-Fa-f]{2}$.

The Limits of This Pattern

Cisco equipment writes MAC addresses as 001b.4411.3ab7 — three groups of four digits separated by dots — which this pattern rejects. Bare twelve-digit forms are also rejected. And a syntactically valid MAC address may still be locally administered, multicast, or simply spoofed: the second-least-significant bit of the first octet tells you the first, and nothing tells you the last.

Testing Before Shipping

A regex that has only been tried against inputs you expect to match is untested. Every pattern needs three kinds of case:

1. Valid inputs that should match, including the awkward-but-legal ones. 2. Invalid inputs that should not, especially near-misses that differ by one character. 3. Adversarial inputs — very long strings, unusual Unicode, and nesting that could trigger catastrophic backtracking.

Paste your own examples into the tester above and watch which lines highlight. A pattern that matches everything you throw at it is usually too permissive rather than correct.

Catastrophic Backtracking

Nested quantifiers over overlapping character classes — (a+)+, (\w+\s?)* — can take exponential time on a non-matching input. On a server that is a denial-of-service bug, not a performance issue. If a pattern is applied to user input, bound the input length first and prefer explicit alternation over nested repetition.

Anchors, Greediness and Backtracking

Three behaviours account for most regex surprises, and this pattern shows all three.

Anchors. ^ and $ pin the match to the start and end of the input. Without them, \d{3} matches the 123 inside abc123def. With m in the flags — as here — they pin to each *line* instead, which is what lets one pattern be tested against a list.

Greediness. .* takes as much as it can and gives back only when forced; .*? takes as little as possible. On , the pattern <.*> matches the whole string and <.*?> matches just .

Backtracking. When a match fails, the engine reverses and tries other splits. Nested quantifiers like (a+)+ make that exponential, and a 30-character input can hang a server — a class of denial of service known as ReDoS. Avoid nesting quantifiers, and prefer explicit character classes over . wherever you can.

Testing It Properly

`javascript const pattern = /^(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}$/gm;

// A global regex keeps lastIndex between calls, so reusing one across // test() calls returns alternating true/false on the same input. pattern.lastIndex = 0;

// Named groups make the result readable const named = /(?\d{4})-(?\d{2})/; const { groups } = '2026-08'.match(named); `

Write the failing cases first. A pattern that accepts everything valid is easy; one that also rejects everything invalid is the hard half, and it is where the bugs are.

When Not to Use a Regex

Structured formats have parsers, and the parser is always more correct: new URL() for URLs, DOMParser for HTML, JSON.parse` for JSON, a date library for dates. Reach for a regex to *find* things in unstructured text, not to validate something a parser understands.

Frequently Asked Questions

Does this pattern handle every valid case?

Cisco equipment writes MAC addresses as `001b.4411.3ab7` — three groups of four digits separated by dots — which this pattern rejects. Bare twelve-digit forms are also rejected. And a syntactically valid MAC address may still be locally administered, multicast, or simply spoofed: the second-least-significant bit of the first octet tells you the first, and nothing tells you the last.

Why does the pattern use the flags it uses?

Flags `gm`. The `g` flag finds every match rather than stopping at the first, and `m` makes `^` and `$` match at each line boundary so a multi-line test string can be checked line by line. Changing them changes the results, so test with the flags you will ship.

Is validating this with a regex the right approach?

For a format check before doing real work, usually yes. For anything security-critical, a regex confirms shape and nothing else — parse the value with a real parser, or verify it against the system that owns it, before trusting it.

Related Tools

Explore other tools you might find useful:

More Regex Tester & Debugger tools

You might also need