Reputation: 59397
Maybe I'm not understanding something, but can somebody explain to me why the following code is behaving the way it is:
/^[1-9]\d*(\.\d{2})?$/.test('0.50') === false;
/^\.\d+$/.test('0.50') === false;
/^([1-9]\d*(\.\d{2})?)|(\.\d+)$/.test('0.50') === true; // <-- WTF?
What's going on here? As you can see the 3rd expression is composed of the first two joined by the |
operator. Since each one tests false
, isn't false | false == false
? Or am I missing a basic concept with regular expressions?
I've tried this in the browser, and with nodejs. Same result either way.
Upvotes: 2
Views: 112
Reputation: 11552
This is because of precedence of operators.
Your expression is ^[1-9][0-9]*(\.\d{2})?
or \.\d+$
.
If you do the following:
/^([1-9][0-9]*(\.\d{2})?)$|^(\.\d+)$/.test('0.50')
you will get false
as you expect.
(Note extra $ and ^ at the boundaries).
More details: in your second part of last expression you no longer require .
to be the first character.
Upvotes: 2
Reputation: 10786
Yeah, but that isn't false | false. I'll add some more parentheses to make it clear what the third regex is evaluating as:
/(^([1-9]\d*(\.\d{2})?))|((\.\d+)$)/.test('0.50') === true; // <-- WTF?
Upvotes: 0
Reputation: 26930
When you use alternation like this, you must also enclose the different groups in ()
/^(?:([1-9][0-9]*(\.\d{2})?)|(\.\d+))$/
Otherwise your regex behaves completely differently.
Upvotes: 0