rossipedia
rossipedia

Reputation: 59397

Javascript regular expression | construct - possible inconsistency

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

Answers (3)

Krizz
Krizz

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

Dan
Dan

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

FailedDev
FailedDev

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

Related Questions