Reputation: 7080
I have a code as below:
var regexp = /((^\u002b[6][0]([1-9]{2}))|(^[0]([1-9]{1})))((\s)|(\u002d)|(\s\u002d\s)?)(\d{3,})((\s)|(\u002d)|(\s\u002d\s)?)(\d{3})(\d)?$/,
str = '+60123456789',
boo = 'false';
(!regexp.test(str)) ? boo = 'false' : boo = 'true';
console.log(boo);
I tested the code and the result returned boo = 'true'
on this jsFiddle but boo = 'false'
on my localhost.
Why is that? Is there anything wrong with my regexp code?
EDIT :
Thanks @Cerbrus and @smnbbrv for pointing out my weird ternary statement.
I corrected it but still getting different result in jsFiddle and my localhost.
var regexp = /((^\u002b[6][0]([1-9]{2}))|(^[0]([1-9]{1})))((\s)|(\u002d)|(\s\u002d\s)?)(\d{3,})((\s)|(\u002d)|(\s\u002d\s)?)(\d{3})(\d)?$/,
str = '+60123456789',
boo = 'false';
boo = regexp.test(str) ? 'true' : 'false';
console.log(boo);
EDIT 2:
I made a mistake at the previous jsFiddle. Corrected it here but still getting discrepancy.
As requested by @Wiktor Stribiżew, my regexp is to filter numbers. It should accept any number starting with either +60
follow by any two number or 0
follow by any one number. The middle part is just to allow whitespaces and hyphens.
Apparently I also caused a minor fight between @Jaromanda X and @Newbee Dev (who I appreciate a lot for helping!). My str value is identical after checking. And localhost is indeed still showing different result.
EDIT 3 :
To @Joe : I ran my localhost using Microsoft WebMatrix 3, for that matters. And both instances are using the same browser.
EDIT 4 :
Thanks @Joe for his detailed examination of my regex here. However, the discrepancy on my end still persists.
Updated the regexp according to his advice.
regexp = /((^\u002b[6][0]([1-9]{2}))|(^[0]([1-9]{1})))((\s)|(\u002d)|(\s\u002d\s)?)(\d{3,4})((\s)|(\u002d)|(\s\u002d\s)?)(\d{3})(\d)?$/;
^
Upvotes: 2
Views: 208
Reputation: 28326
You regex has a slight ambiguity.
/((^\u002b[6][0]([1-9]{2}))|(^[0]([1-9]{1})))((\s)|(\u002d)|(\s\u002d\s)?)(\d{3,})((\s)|(\u002d)|(\s\u002d\s)?)(\d{3})(\d)?$/
If we break this down one part at a time:
((^\u002b[6][0]([1-9]{2}))|(^[0]([1-9]{1})))
will match +60
followed by 2 non-zero digits, or 0 followed by 1 non-zero digit
((\s)|(\u002d)|(\s\u002d\s)?)
will match a single space, a single dash or a dash surrounded by spaces, or nothing.
(\d{3,})
then matches 3 or more digits <- This is where the ambiguity lies. Depending on how greedy the regex matcher is, this may consume to the end of the string if there are only digits left.
((\s)|(\u002d)|(\s\u002d\s)?)
repeat of before
(\d{3})
matches exactly 3 digits <- if the previous pattern greedily matched to the end of the string, this pattern will not match as all of the digits were consumed.
(\d)?
one digit or no digits
tl;dr
This regular expression is completely valid, but will give different results depending on the greediness setting of the engine that applies it.
Upvotes: 2