Reputation: 1912
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 ?
Upvotes: 2
Views: 6481
Reputation: 3541
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:
str.split(",")
to get an array of candidate MAC addressesvar 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
Upvotes: 3
Reputation: 14524
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! ^
Upvotes: 5