In this format:
3D:F2:C9:A6:B3:4F
or:
3D-F2-C9-A6-B3-4F
The standard (IEEE 802) format for printing MAC-48 addresses in human-friendly form is six groups of two hexadecimal digits, separated by hyphens
-
or colons:
.
So:
^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$
A little hard on the eyes, but this:
/^(?:[[:xdigit:]]{2}([-:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/
will enforce either all colons or all dashes for your MAC notation.
(A simpler regex approach might permit A1:B2-C3:D4-E5:F6
, for example, which the above rejects.)
This regex matches pretty much every mac format including Cisco format such as 0102-0304-abcd
^([[:xdigit:]]{2}[:.-]?){5}[[:xdigit:]]{2}$
Example strings which it matches:
01:02:03:04:ab:cd
01-02-03-04-ab-cd
01.02.03.04.ab.cd
0102-0304-abcd
01020304abcd
Mixed format will be matched also!
delimiter: ":","-","."
double or single: 00 = 0, 0f = f
/^([0-9a-f]{1,2}[\.:-]){5}([0-9a-f]{1,2})$/i
or
/^([0-9a-F]{1,2}[\.:-]){5}([0-9a-F]{1,2})$/
exm: 00:27:0e:2a:b9:aa, 00-27-0E-2A-B9-AA, 0.27.e.2a.b9.aa ...
See this question also.
Regexes as follows:
^[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}$
^[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}$
Be warned that the Unicode property \p{xdigit}
includes the FULLWIDTH versions. You might prefer \p{ASCII_Hex_Digit}
instead.
The answer to the question asked might be best answered — provided you have a certain venerable CPAN module installed — by typing:
% perl -MRegexp::Common -lE 'say $RE{net}{MAC}'
I show the particular pattern it outputs here as lucky pattern number 13; there are many others.
This program:
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings qw<FATAL all>;
my $mac_rx = qr{
^ (?&MAC_addr) $
(?(DEFINE)
(?<MAC_addr>
(?&pair) (?<it> (?&either) )
(?: (?&pair) \k<it> ) {4}
(?&pair)
)
(?<pair> [0-9a-f] {2} )
(?<either> [:\-] )
)
}xi;
while (<DATA>) {
chomp;
printf("%-25s %s\n", $_ => /$mac_rx/ ? "ok" : "not ok");
}
__END__
3D:F2:C9:A6:B3:4F
3D:F2:AC9:A6:B3:4F
3D:F2:C9:A6:B3:4F:00
:F2:C9:A6:B3:4F
F2:C9:A6:B3:4F
3d:f2:c9:a6:b3:4f
3D-F2-C9-A6-B3-4F
3D-F2:C9-A6:B3-4F
generates this output:
3D:F2:C9:A6:B3:4F ok
3D:F2:AC9:A6:B3:4F not ok
3D:F2:C9:A6:B3:4F:00 not ok
:F2:C9:A6:B3:4F not ok
F2:C9:A6:B3:4F not ok
3d:f2:c9:a6:b3:4f ok
3D-F2-C9-A6-B3-4F ok
3D-F2:C9-A6:B3-4F not ok
Which seems the sort of thing you're looking for.
You can use this : (([0-9A-Fa-f]{2}[-:]){5}[0-9A-Fa-f]{2})|(([0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})
Thanks a lot to @Moshe for the great answer above. After doing some more research I would like to add my extra findings, both in regards to IEEE 802 and enforcing consistent separator usage in regex.
The standard (IEEE 802) format for printing MAC-48 addresses in human-friendly form is six groups of two hexadecimal digits, separated by hyphens -. It is however, widely adopted convention to also allow colon :, and three groups of four hexadecimal digits separated by periods ..
Full credit to @Moshe here for his initial statement, and to @pilcrow for pointing out that IEEE 802 only covers hypens.
Here is a regex that enforces that same separator is used throughout the mac address:
^(?:(?:[0-9A-Fa-f]{2}(?=([-:]))(?:\1[0-9A-Fa-f]{2}){5}))$
And here is an additional one that allows for use of no separator at all:
^(?:(?:[0-9A-Fa-f]{2}(?=([-:]|))(?:\1[0-9A-Fa-f]{2}){5}))$
If you are using PHP, you can make use of filter_var()
:
// Returns $macAddress, if it's a valid MAC address
filter_var($macAddress, FILTER_VALIDATE_MAC);
As it seems, it supports MAC addresses in the following formats (x: a hexadecimal digit):
xx:xx:xx:xx:xx:xx
xx-xx-xx-xx-xx-xx
xxxx.xxxx.xxxx
The python version could be:
re.compile(r'\A(?:[\da-f]{2}[:-]){5}[\da-f]{2}\Z',re.I)
/^(([a-fA-F0-9]{2}-){5}[a-fA-F0-9]{2}|([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}|([0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})?$/
The regex above validate all the mac addresses types below :
01-23-45-67-89-ab
01:23:45:67:89:ab
0123.4567.89ab
Maybe the shortest possible, in PCRE (Perl-Compatible Regular Expressions, e.g. used in PHP):
/([\da-f]{2}[:-]){5}[\da-f]{2}/i
I don't think that the main RegEx is correct as it also classifies
'3D-F2-C9:A6-B3:4F'
as a valid MAC Address, even though it is not correct. The correct one would be:
((([a-zA-z0-9]{2}[-:]){5}([a-zA-z0-9]{2}))|(([a-zA-z0-9]{2}:){5}([a-zA-z0-9]{2})))
So that every time you can choose ':' or '-' for the whole MAC address.
to match both 48-bit EUI-48 and 64-bit EUI-64 MAC addresses:
/\A\h{2}([:\-]?\h{2}){5}\z|\A\h{2}([:\-]?\h{2}){7}\z/
where \h is a character in [0-9a-fA-F]
or:
/\A[0-9a-fA-F]{2}([:\-]?[0-9a-fA-F]{2}){5}\z|\A[0-9a-fA-F]{2}([:\-]?[0-9a-fA-F]{2}){7}\z/
this allows '-' or ':' or no separator to be used
A mac address can be 48 bits or 64 bits.
ad:12:13:fc:14:ee // 48 bit, with colons
ad-12-13-fc-14-ee // 48 bit, with dashes
ad1213fc14ee // 48 bit, without any delimiter
AD:12:13:FC:14:EE // 48 bit, uppercase.
AD:12:13:FC:14:EE:FF:FF // 64 bit, uppercase
ad:12:13:fc:14:ee:13:ad // 64 bit, lowercase
ad-12-13-fc-14-ee-ff-ad // 64 bit, with dashes
ad1213fc14eeffae // 64 bit, without any delimter
If you are looking for a regular expression that can validate both and all the above cases (which are valid) the following would work:
For 48 bit we can use this:
^[0-9A-Fa-f]{2}([:-]?)(?:[0-9A-Fa-f]{2}\1){4}[0-9A-Fa-f]{2}$
For 64 bit we can use this:
^[0-9A-Fa-f]{2}([:-]?)(?:[0-9A-Fa-f]{2}\1){6}[0-9A-Fa-f]{2}$
If you are looking for a single regex to validate both kinds of mac addresses, use an OR operator to concat them.
You can use following procedure by passing mac address for validation,
private static final String MAC_PATTERN = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$";
private boolean validateMAC(final String mac){
Pattern pattern = Pattern.compile(MAC_PATTERN);
Matcher matcher = pattern.matcher(mac);
return matcher.matches();
}
PHP Folks:
print_r(preg_match('/^(?:[0-9A-F]{2}[:]?){5}(?:[0-9A-F]{2}?)$/i', '00:25:90:8C:B8:59'));
Need Explanation: http://regex101.com/r/wB0eT7
As a MAC address can be 6 or 20 bytes (infiniband, ...) the correct answer is:
^([0-9A-Fa-f]{2}:){5}(([0-9A-Fa-f]{2}:){14})?([0-9A-Fa-f]{2})$
you can replace : with [:-.]? if you want different separators or none.
This could be used tested in sublime with my MAC address
This solution will only work with ideal MAC address That will look like this.. XX:XX:XX:XX:XX:XX
(([a-fA-F0-9]{2}[:]){5}[a-fA-F0-9]{2})
Cisco format:
([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}
Matches:
1111.abcd.2222
If you need spaces between numbers, like this variant
3D : F2 : C9 : A6 : B3 : 4F
The regex changes to
"^([0-9A-Fa-f]{2}\\s[:-]\\s){5}([0-9A-Fa-f]{2})$"
This one is a small one:
(([0-9A-F]{2}[:-]?){6})
Have in mind, that weird mix of several chars or separators could pass.
I'm going to pile on with an answer here because there is no single solution to scan both 48-bit and 64-bit MAC addresses in one regex, and many of the other solutions allow mixed delimiters or can't handle no delimiters. I also took advantage of the 'ignore-case' flag to shorten the basic hexadecimal character group that appears three times here:
/[\da-f]{2}(?=([-:]?))((\1[\da-f]{2}){2})?(\1[\da-f]{2}){5}/gi
[\da-f] is the shortest way to specify hexadecimal digits, scan upfront for two of them. Then do a lookahead to load up capture group 1 with the delimiter you want to use (or none). Then create an optional pair of hexadecimal pairs to handle the 64-bit case. Then finish with 5 hexadecimal pairs. Once again specify the /i flag to ignore case on the a-f.
If I were implementing this, I would also add a negative lookbehind near the beginning and a negative lookahead at the end to ensure I rejected excess hex-delimiter pairs, but that just complicates the answer and not all regex implementations handle lookbehinds or have all the same features, so I left that out.
the best answer is for mac address validation regex
^([0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])$