0

I want to have one regular expression to validate following MAC address formats.

  1. 01-23-45-67-89-ab or 01-23-45-67-89-AB
  2. 01:23:45:67:89:ab or 01:23:45:67:89:AB
  3. 0123.4567.89ab or 0123.4567.89AB
  4. 0123456789ab or 0123456789AB

All of the above are valid MAC Address Formats.

MAC Address should have all CAPITAL letters or all small letters(but not both) of English alphabets from set [a-f A-F] .

Currently i am using 6 regex pattern and i have combined them using or for validation, which doesn't look good.

Here is my Javascript Code:

    var value='01-23-45-67-89-ab';
    var regex = new RegExp("^([0-9a-f]{2}){6}$");
    var regex1 = new RegExp("^([0-9A-F]{2}){6}$");
    var regex2 = new RegExp("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$");
    var regex3 = new RegExp("^([0-9a-f]{2}[:-]){5}([0-9a-f]{2})$");
    var regex4 = new RegExp("^([0-9a-f]{4}[\\.]){2}[0-9a-f]{4}$");
    var regex5 = new RegExp("^([0-9A-F]{4}[\\.]){2}[0-9A-F]{4}$");

    if (regex.test(value) || regex1.test(value)|| regex2.test(value)|| regex3.test(value)|| regex4.test(value)|| regex5.test(value)){
            return true;
        }
    else{
        return false;
    }

Is ther a better way to combine them all without using or? I am not good with regex. Any Help would be appreciated.

Arvind
  • 2,338
  • 1
  • 9
  • 20

2 Answers2

4

Yes those regexs can be simplified and then combined into a single regex to match all those cases.

This is them combined:

^([0-9A-F]{12}|(?:[0-9A-F]{2}:){5}[0-9A-F]{2}|(?:[0-9A-F]{2}-){5}[0-9A-F]{2}|(?:[0-9A-F]{4}\.){2}[0-9A-F]{4})$

Regular expression visualization

Note that you don't have to duplicate the regex to account for both Lower and Upper case and that you can just specify "i" as the second parameter to new RegExp() to specify that it should be matched case insensitive.

var regex = new RegExp("^([0-9A-F]{12}|(?:[0-9A-F]{2}:){5}[0-9A-F]{2}|(?:[0-9A-F]{2}-){5}[0-9A-F]{2}|(?:[0-9A-F]{4}\.){2}[0-9A-F]{4})$", "i");

if( regex.test( value ) )
{
    //true
}

As requested in the comments to this answer here is a version which doesn't allow case mixing...

^([0-9A-F]{12}|[0-9a-f]{12}|(?:[0-9A-F]{2}:){5}[0-9A-F]{2}|(?:[0-9a-f]{2}:){5}[0-9a-f]{2}|(?:[0-9A-F]{2}-){5}[0-9A-F]{2}|(?:[0-9a-f]{2}-){5}[0-9a-f]{2}|(?:[0-9A-F]{4}\.){2}[0-9A-F]{4}|(?:[0-9a-f]{4}\.){2}[0-9a-f]{4})$
AeroX
  • 3,209
  • 2
  • 21
  • 38
  • Where did you get the graphic? – ooga May 06 '14 at 14:41
  • 2
    The graphic visualisation is from [Debuggex](https://www.debuggex.com/r/3fOdfwTO7Vt0GU24) – AeroX May 06 '14 at 14:43
  • `AB:AB:AB:AB:AB-AB` is correct according to your regex. my mac validation is also not correct i think in my question. – Arvind May 06 '14 at 15:44
  • `[:-]` should be separated. then it will be fine i think. – Arvind May 06 '14 at 15:46
  • @Arvind I've modified the answer but this makes the regex slightly longer again now – AeroX May 06 '14 at 15:48
  • Also i dont want to ignore the case sensitivity using `i`. I wanted either all capitals or all smalls. Not mixtures. Thats why i had to repeat. – Arvind May 06 '14 at 16:10
  • @Arvind I know it's not what you've asked for but I personally would just convert them all to all upper-case. If they are being typed in via a UI you could convert them as they are typed. To modify the regex to distinguish between upper and lower case would double the size of the regex – AeroX May 06 '14 at 16:16
  • 1
    Thanks for the edit in the answer. But i think i will go with the your suggestion to ignore the cases and convert them all to lowercase. – Arvind May 06 '14 at 16:24
2

There are no different formats of a MAC address, only different ways it may be presented. The MAC address is a 12 character long hexadecimal string.

You should change the approach. Instead of accepting various formats and matching user input against several regular expressions, transform the user input and match it against one regex.

  • accept user input
  • remove colons (:)
  • remove dashes (-)
  • remove spaces ( )
  • convert to all uppercase
  • validate
marekful
  • 13,318
  • 5
  • 30
  • 52