MAC Address Regular Expression – Free, Online, Private
Matches a six-octet MAC address with colons or dashes, not both mixed.
- aa:bb:cc:dd:ee:ff
- AA-BB-CC-DD-EE-FF
The pattern
The pattern matches aa:bb:cc:dd:ee:ff and AA-BB-CC-DD-EE-FF. It does not match a bare 12-digit hex string, and it does not match a five-octet truncation. The separator is either a colon or a dash, and the same choice is used in every position because each separator is its own character class on a repeated group. Mixing colon and dash in one address fails, which is what you want when you are normalizing input.
The source is ^(?:[0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$. The flags on this page are im. i means case-insensitive. m means ^ and $ match at line breaks, which is how the sample can show several candidates. g is not set. The tester finds non-overlapping matches, and without g a pattern with no anchor still reports the matches it walks. The box under the title is a tester with this pattern and the sample already filled in. Edit either one. Nothing you type is uploaded. The same tester, without a preset, is the regex tool.
How to read it
[0-9a-fA-F]{2} is one octet. [:-] is the separator. The group repeats five times, which accounts for five octets and five separators, and a final octet completes the six. The i flag is belt and braces with the class. Anchors and m make the sample one address per line. There is no optional separator. If you need the Cisco dotted form aabb.ccdd.eeff, that is a different pattern with a different group size.
What it will not do
The pattern does not know which addresses are multicast or locally administered. The first octet's bits carry that, and a regex is a bad place to decode them. It does not accept dots as separators. It does not accept a missing leading zero. a:b:c:d:e:f fails because each octet must be two digits. Normalize first if your source drops the zero. The pattern is case-insensitive and does not rewrite the address. The tester shows the match. It does not store a NIC.
A match is not a parsed value. An email pattern does not send mail, a UUID pattern does not allocate an id, and a password pattern does not store a password. When the next step needs a real parser, use one: the URL constructor, a date library, a semver library, or the converters on this site. The expression is the part you can see.
JavaScript, Python, and Go
The JavaScript snippet uses the RegExp constructor so the source does not have to be escaped for a literal slash. The Python snippet uses a normal string with the same escapes JSON would emit, which keeps \d as a regex digit class. Go's snippet uses a raw string. If the pattern contains a lookahead, the Go snippet says so and does not call MustCompile, because RE2 would reject it at runtime.
JavaScriptconst re = new RegExp("^(?:[0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$", "im");
const found = text.match(re);
console.log(found ? found[0] : "no match");
Pythonimport re
pattern = re.compile("^(?:[0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$", re.IGNORECASE | re.MULTILINE)
found = pattern.search(text)
print(found.group(0) if found else "no match")
Gopackage main
import (
"fmt"
"regexp"
)
func main() {
text := ""
re := regexp.MustCompile(`(?i)(?m)^(?:[0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}$`)
fmt.Println(re.FindString(text))
}
Frequently asked questions
Are dashes allowed?
Yes, if every separator is a dash. Mixing dashes and colons fails.
Does aabbccddeeff match?
No. The separators are required. This pattern is the written form, not the packed hex.
Can an octet be a single digit?
No. Each octet is exactly two hex digits.
Does this identify the vendor?
No. It only checks the text form. The OUI is a lookup, not a regex.