137

In this format:

3D:F2:C9:A6:B3:4F

or:

3D-F2-C9-A6-B3-4F
kasravnd
  • 94,640
  • 16
  • 137
  • 166
Xaisoft
  • 42,877
  • 83
  • 270
  • 415

22 Answers22

290

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})$
Moshe
  • 55,729
  • 73
  • 263
  • 420
netcoder
  • 61,842
  • 17
  • 117
  • 139
  • Ok this is what I was looking for, but I had: ^([0-9A-F]{2}:|-){5}([0-9A-F]{2})$ – Xaisoft Nov 23 '10 at 20:23
  • I was thinking the : | - would match either and : or a -. – Xaisoft Nov 23 '10 at 20:23
  • 22
    Note that if they are being stored with lower case hexadecimal letters it will not match change the group to [0-9A-Fa-f] to catch both cases – Scott Chamberlain Nov 23 '10 at 20:24
  • 5
    you probably also want to ignore casing – dietbuddha Nov 23 '10 at 20:24
  • Is there a way to only validate it if and only if it has hyphens or colons, for example, it can't have a mixture because of the above regular expression: 3D:F2:C9:A6:B3-4F is valid when it should not be. – Xaisoft Nov 23 '10 at 20:25
  • @Xiasoft you must then do two checks like JYelton's example but you could still use the shortened form. – Scott Chamberlain Nov 23 '10 at 20:26
  • @Xaisoft: Still according to IEEE 802, 3D:F2:C9:A6:B3-4F is a valid MAC address representation. – netcoder Nov 23 '10 at 20:27
  • @Xiasoft, yes, see my answer. – pilcrow Nov 23 '10 at 20:27
  • @netcoder, where did u find this info? I found that a valid MAC is either sepearted by :, -, or 4 groups separted by . – Xaisoft Nov 23 '10 at 21:11
  • @Xaisoft: I recall it's in the OUI spec. I found that out when I was asking myself the same question a while ago. In any case, if you really want to enforce one OR the other, you can do two checks like Scott said. – netcoder Nov 23 '10 at 21:36
  • 5
    ^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$ – Rajavel D Mar 25 '13 at 10:10
  • 2
    As an aside, the quote above concerning "standard format" comes from Wikipedia, not the 802.3 standards body. IEEE 802-2014 actually specifies _hyphens_ for ordinary MAC addresses (§ 8.1 ¶ 3) and _colons_ for the obsolescent bit-reversed notation (¶ 4). Importantly, in practice, _no one observes this_. We simply use one or the other, but never mix them in a single written MAC. – pilcrow Jul 14 '15 at 17:06
  • 1
    I don't think that this 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. – PyFox Apr 05 '19 at 09:57
  • Is there any specific reason for why you wrap the last two statements into parentheses? – Jan Jan 17 '20 at 08:42
26

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

pilcrow
  • 51,771
  • 11
  • 83
  • 128
  • This works, but can you explain what :xdigit is? and I noticed you put the group ([-:]) after the length, what makes that take either all colons or hyphens? – Xaisoft Nov 23 '10 at 20:28
  • 3
    @Xaisoft, `:xdigit:` is short for hex digit, more-or-less another way of saying `[a-fA-F0-9]`. The `\1` refers to the capture group for the first dash or colon `([-:])`, and only matches what matched that first time. – pilcrow Nov 23 '10 at 20:33
  • 2
    +1 for using both capturing and non-capturing groups appropriately, and also for using ```:xdigit:``` (even though that "shorthand" is only just shorter than ```[a-fA-F0-9]``` and equivalent ```/[a-f0-9]/i``` is shorter!) – gb96 Dec 21 '15 at 06:17
  • @pilcrow could you please explain why this mac: `C8:FD:19:55:E6:3A` fails? It's an actual mac address. I modified your regex to accept `:` only `/^(?:[[:xdigit:]]{2}([:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/` Thanks! – Sam May 27 '19 at 15:37
  • @Sam, perhaps you could pose a separate question? Both my regex and your modification work for me on that input... – pilcrow May 28 '19 at 02:31
  • 1
    In my mind this is the better answer as it actually checks the mixed use of ":" and "-". – Ray Oei Oct 11 '19 at 18:52
9

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!

pilcrow
  • 51,771
  • 11
  • 83
  • 128
Vesselin Yanev
  • 123
  • 1
  • 8
  • This will match separators after any of the first five octets, meaning that it will accept `aa.aa.bbbb.cccc`, for example. – pilcrow Nov 06 '15 at 04:46
  • 1
    **#notAllFormats** If you have access to an OSX system with WiFi, run `/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I`, and look for the BSSID line, if any octet is under 0x10 leading zero is dropped (`%x` or `%2x` rather than `%02x` `printf` format used?) – nhed Nov 09 '17 at 15:24
8

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 ...
Andro Selva
  • 51,960
  • 51
  • 189
  • 237
lioncub
  • 89
  • 1
  • 2
  • 2
    The second will incorrectly match strings which contain non-hex characters such as g. – Binary Phile Feb 25 '15 at 15:32
  • The second one is not valid in most flavors, except for BRE/ERE, which supports character range collation. However, support for character range collation varies among implementation, so the result may vary. – nhahtdh May 06 '15 at 03:14
  • Another thing is that the groups must have exactly 2 hexa-digits. – nhahtdh May 06 '15 at 03:30
  • In theory all mac addresses returned by programs in the wild would follow some standard like 2 hex digits in each separate group. However, some non-standardized [Unix variants](http://www.coffer.com/mac_info/locate-unix.html) shorten the output when there is a leading zero, leaving only 1 hex char in some cases. Hence the need for the `{1,2}` regex – TrinitronX Jun 30 '16 at 04:11
  • However, the character set from `[0-9a-F]` should probably be rewritten as: `[0-9a-fA-F]` – TrinitronX Jun 30 '16 at 04:14
5

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.

Community
  • 1
  • 1
tchrist
  • 74,913
  • 28
  • 118
  • 169
5

This link might help you. 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})

4

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}$
Community
  • 1
  • 1
JYelton
  • 32,870
  • 25
  • 119
  • 184
  • 1
    Isn't there a way to shorten it by doing groups? and how can I combine the regex to have either a : or a - without having 2 separate regular expressions? – Xaisoft Nov 23 '10 at 20:21
  • The shortened form that netcoder provides will work also. Using one or the other may be based on whether you need to capture any of the MAC address or just validate it on the whole. – JYelton Nov 23 '10 at 20:29
  • It needs to be validated on the whole, so if it either contains all hyphens or all colons. If it contains a mix, it is not a valid MAC. – Xaisoft Nov 23 '10 at 20:31
  • 2
    @Xaisoft: Like I said in my answer's comment, mixing colons and hyphens is valid according to the specification. – netcoder Nov 23 '10 at 20:35
  • What source are you getting MAC addresses from that might have a mix of delimiters? If they are coming from an actual machine/NIC, you likely won't have that issue. If it is user-entered data, just perform a string replace to make all the delimiters consistent. – JYelton Nov 23 '10 at 20:36
2

The python version could be:

re.compile(r'\A(?:[\da-f]{2}[:-]){5}[\da-f]{2}\Z',re.I)
Juan Diego Godoy Robles
  • 12,742
  • 2
  • 36
  • 47
2
/^(([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
2

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 forms (x: a hexadecimal number):

xx:xx:xx:xx:xx:xx
xx-xx-xx-xx-xx-xx
xxxx.xxxx.xxxx
MAChitgarha
  • 2,189
  • 2
  • 19
  • 30
Saurabh Chandra Patel
  • 9,983
  • 3
  • 77
  • 72
2
/(?:[A-Fa-f0-9]{2}[:-]){5}(?:[A-Fa-f0-9]{2})/
bcosca
  • 16,475
  • 5
  • 36
  • 50
2

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.

PyFox
  • 353
  • 2
  • 11
1

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

Tilo
  • 31,645
  • 4
  • 72
  • 101
1

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}))$

Regex101 demo

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}))$

Regex101 demo

Robert Axelsen
  • 474
  • 3
  • 7
0

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();             
}
0

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

bn00d
  • 1,008
  • 3
  • 15
  • 20
0

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})$"
RexSplode
  • 1,347
  • 1
  • 11
  • 22
0

Maybe the shortest possible, in PCRE (Perl-Compatible Regular Expressions, e.g. used in PHP):

/([\da-f]{2}[:-]){5}[\da-f]{2}/i
MAChitgarha
  • 2,189
  • 2
  • 19
  • 30
0

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.

0

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.

Shwetabh Shekhar
  • 1,151
  • 15
  • 25
-1

This one is a small one:

(([0-9A-F]{2}[:-]?){6})

Have in mind, that weird mix of several chars or separators could pass.

esguti
  • 150
  • 6
-4

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])$
andrewsi
  • 10,954
  • 132
  • 33
  • 48