Question

Suppose I have a list of mac address, eg: "00:11:22:33:44:55,11:22:33:44:55:66,22:33:44:55:66:77"

I would like to do regular expression check on that list.

var re = /(([A-Fa-f0-9]{2}[:]){5}[A-Fa-f0-9]{2}[,]?)+/g

However, it does not work. Here are the input tests.

var t1 = "11:22:33:44:55:66";
var t2 = t1 + ",12:22:33:44:55:66";
var t3 = t1 + ",11asdfasdf:22:33:44:55:66";
var t4 = t1 + ",haha";
var t5 = t1 + ",";
var t6 = "123123123123";
var t7 = t1 + ",33:44:55:66:77:88:";
var t8 = t1 + ",33:44:55:66:77:88asdfasdfasdfasdfasdfasd";
var t9 = t1 + ",dfasdfasdfasdfasdfasd";
var t10 = t2 + ",12:33:44:55:66:77";
var t11 = t2 + ",wahaa";

console.log("t1: [" + t1 + "] " + re.test(t1));
console.log("t2: [" + t2 + "] " + re.test(t2));
console.log("t3: [" + t3 + "] " + re.test(t3));
console.log("t4: [" + t4 + "] " + re.test(t4));
console.log("t5: [" + t5 + "] " + re.test(t5));
console.log("t6: [" + t6 + "] " + re.test(t6));
console.log("t7: [" + t7 + "] " + re.test(t7));
console.log("t8: [" + t8 + "] " + re.test(t8));
console.log("t9: [" + t9 + "] " + re.test(t9));
console.log("t10: [" + t10 + "] " + re.test(t10));
console.log("t11: [" + t11 + "] " + re.test(t11));   

Result

t1: [11:22:33:44:55:66] true 
t2: [11:22:33:44:55:66,12:22:33:44:55:66] true 
t3: [11:22:33:44:55:66,11asdfasdf:22:33:44:55:66] false 
t4: [11:22:33:44:55:66,haha] true 
t5: [11:22:33:44:55:66,] false 
t6: [123123123123] false 
t7: [11:22:33:44:55:66,33:44:55:66:77:88:] true 
t8: [11:22:33:44:55:66,33:44:55:66:77:88asdfasdfasdfasdfasdfasd] false 
t9: [11:22:33:44:55:66,dfasdfasdfasdfasdfasd] true 
t10: [11:22:33:44:55:66,12:22:33:44:55:66,12:33:44:55:66:77] true
t11: [11:22:33:44:55:66,12:22:33:44:55:66,wahaa] false

Anyone can tell me why t7, t9 and t4 will return true? Moreover, when I type re.test(t11) on chrome console, I found that the result will switching between true and false. Anyone know why ?

Was it helpful?

Solution

Since your regular expression is already designed to match all mac addresses in a string (instead of just one at a time), you can fix this bug by removing the g flag. Also, to prevent matching only part of the string, you need to include the ^ and $ characters at the beginning and end of your regular expression.

var re = /^(([A-Fa-f0-9]{2}[:]){5}[A-Fa-f0-9]{2}[,]?)+$/

Because you are using a global regular expression (due to the g at the end), the regular expressions keeps state about its last match, which will affect future matches.

Specifically, the RegExp object you store in the re variable has a lastIndex that is updated to point to the first character after each match. Future matches are performed starting at that index, even if you match against a new string. Once a match is unsuccessful, lastIndex is reset to 0.

Graphically, this is what matches and where re.lastIndex points after each match:

    t1:  11:22:33:44:55:66
                          ^
    t2:  11:22:33:44:55:66,12:22:33:44:55:66
                                            ^
    t3:  11:22:33:44:55:66,11asdfasdf:22:33:44:55:66 No match!
         ^ Since there was no match, lastIndex is reset to 0.
    t4:  11:22:33:44:55:66,haha
                           ^
    t5:  11:22:33:44:55:66, No match!
         ^ 
    t6:  123123123123 No match!
         ^
    t7:  11:22:33:44:55:66,33:44:55:66:77:88:
                                            ^
    t8:  11:22:33:44:55:66,33:44:55:66:77:88asdfasdfasdfasdfasdfasd No match!
         ^
    t9:  11:22:33:44:55:66,dfasdfasdfasdfasdfasd
                           ^
    t10: 11:22:33:44:55:66,12:22:33:44:55:66,12:33:44:55:66:77
                                                              ^
    t11: 11:22:33:44:55:66,12:22:33:44:55:66,wahaa No match!
         ^

OTHER TIPS

You need to use the ^ start of line anchor, and the $ End of line anchor. Your tests only verify that the string contains a correct match, not that the whole string is correct.

var str = 'This is a sentence';
var re = /e/;
re.test(str); // returns true

var re2 = /^e$/;
re2.test(str); // returns false
re2.test("e"); // returns true

For you to get the most precise answer, I would suggest:

  1. Split on "," str.split(",") to get an array of candidate MAC addresses
  2. Match each element of the Array with the following modified regex: var re = /^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$/i I made the regex case-insensitive with the i flag, and also added a - because sometimes MAC addresses are written as such: 3D-F2-C9-A6-B3-4F
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top