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
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.