replay
replay

Reputation: 3809

Regex to match MAC address and also extract it's values

I'm trying to first check if a string confirms the format of a MAC address, and if it does I would like to extract all the byte values out of the string.

So far I wrote this, and it successfully matches if the format of a mac address is correct or not:

 mac_regx = re.compile(r'^([0-9A-F]{1,2})(\:[0-9A-F]{1,2}){5}$', re.IGNORECASE)

But when I use this regex to extract the byte values, I'm only getting the first and the last one:

(Pdb) print(mac_regx.findall('aa:bb:cc:dd:ee:ff'))
[('aa', ':ff')]

I know I could simply split by : and that would do the job. I was just hoping to be able to do both, the matching and value extraction, in only one step with one regex.

Upvotes: 5

Views: 5578

Answers (3)

Sean F
Sean F

Reputation: 4605

There are a number of different possible formats. So it may be difficult for a single regex to handle them all.

If you are willing to use code rather than a regex, the IPAddress Java library will handle various formats at the same time.

The library will read most common formats for MAC addresses, like aa:bb:cc:dd:ee:ff, aa-bb-cc-dd-ee-ff, aabb.ccdd.eeff, aa bb cc dd ee ff, it supports addresses that are 48 or 64 bits, and also allows you to specify ranges of addresses like aa-ff:bb:cc:*:ee:ff

Verify if an address is valid:

    String str = "aa:bb:cc:dd:ee:ff";
    MACAddressString addrString = new MACAddressString(str);
    try {
         MACAddress addr = addrString.toAddress();
         //extract values with addr.getSegment(i).getLowerSegmentValue()
         ...
    } catch(AddressStringException e) {
        //e.getMessage provides validation issue
    }

Upvotes: 0

Barmaley
Barmaley

Reputation: 1232

I cheated and used variation submitted by mauro.stettler. I think this is pretty clear and straight forward one liner. mac_validation should return True or False. Thanks Mario!

import re
mac_validation = bool(re.match('^' + '[\:\-]'.join(['([0-9a-f]{2})']*6) + '$', mac_input.lower()))

Upvotes: 0

Vedran Šego
Vedran Šego

Reputation: 3765

If you want all the matches, you should avoid using {5}:

mac_regx = re.compile(r'^([0-9A-F]{1,2})\:([0-9A-F]{1,2})\:([0-9A-F]{1,2})\:([0-9A-F]{1,2})\:([0-9A-F]{1,2})\:([0-9A-F]{1,2})$', re.IGNORECASE)

or, shorter,

mac_regx = re.compile(r'^([0-9A-F]{1,2})' + '\:([0-9A-F]{1,2})'*5 + '$', re.IGNORECASE)

You could also make a list of 6 occurrences of a string '[0-9A-F]{1,2})' and join them with '\:'.

Upvotes: 2

Related Questions