PatternRegex

Match a MAC address

Match hardware MAC addresses in the six-pair colon or dash notation — for log greps, inventory sheets and DHCP configs.

Last updated

Patterng
(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}
Open in Regex Tester & Builder

Matches

  • 00:1A:2B:3C:4D:5E
  • 00-1a-2b-3c-4d-5e

Doesn’t match

  • 00:1A:2B:3C:4D
  • 001A.2B3C.4D5E

Why it’s written this way

Five "pair plus separator" groups and a final bare pair gives exactly six octets. The [:-] class accepts both the Unix colon convention and the Windows dash convention in one pattern.

Edge cases to know

  • →Mixed separators (00:1A-2B:3C-4D:5E) match, since each position chooses independently — validate consistency separately if it matters.
  • →Cisco's dotted-quad form (001a.2b3c.4d5e) is a different shape and needs its own alternative.
  • →It says nothing about whether the address is real — for vendor lookup, drop it into the MAC Address Analyzer tool.

Part by part

(?:
Opens a non-capturing group around the repeated "pair plus separator" unit, so the five repetitions do not clutter your match array.
[0-9A-Fa-f]
A single hexadecimal digit. Both letter cases are listed explicitly, which is why the pattern works without the i flag.
{2}
Exactly two hex digits — one octet. Not one, not three.
[:-]
The separator, accepting either the colon convention used on Unix or the dash convention used in Windows output.
){5}
Repeats the pair-and-separator unit five times, which accounts for five of the six octets and all five separators.
[0-9A-Fa-f]{2}
The sixth and final octet, written separately because it is the one pair with no separator after it.

Common mistakes

  • (?:[0-9A-Fa-f]{2}[:-]){6}

    Repeating six times instead of five and dropping the trailing pair requires a separator after the last octet, so a real address never matches and one with a stray trailing colon does.

    (?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}
  • [0-9A-Fa-f:-]{17}

    Counting characters rather than describing structure accepts any 17-character mix from the class, so ":::::::::::::::::" passes and a valid address written with dots does not.

  • ([0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}

    A capturing group inside a repetition only ever retains its last iteration, so the capture holds the fifth octet and nothing useful — the group should be non-capturing.

Questions

Why does this work without the case-insensitive flag?

Because the character class spells out both cases as [0-9A-Fa-f] rather than relying on the i flag. That matters when the pattern is embedded in a larger expression where turning on case-insensitivity would loosen other parts of it.

Does it accept an address with mixed separators?

Yes — each [:-] position chooses independently, so "00:1A-2B:3C-4D:5E" matches. Real hardware never emits that, so if consistency matters, capture the first separator and backreference it instead.

How do I also match Cisco's dotted format?

The 001a.2b3c.4d5e form groups four hex digits at a time rather than two, so it needs its own alternative: add |(?:[0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4} to cover both notations in one pattern.

Does a match mean the address is real?

No. The pattern checks shape only — it cannot tell you whether the address is assigned, whether the vendor prefix exists, or whether it is a locally administered or multicast address. Those need a lookup against the OUI registry.

What about addresses written with no separators at all?

Bare twelve-digit forms such as 001A2B3C4D5E turn up in switch tables and vendor exports, and this pattern will not match them because it requires separators. Use [0-9A-Fa-f]{12} for that case, but anchor it — unanchored, it will happily pull twelve digits out of the middle of any longer hex string.

Related in Patterns