jc127
jc127

Reputation: 352

regex works individually but doesn't work when combined with |

I'm trying to write something like eval(), here are some of the requirements:

if the expression contains non-numeric character other than [+, -, *, /, .],
or [+, -] is followed by [*, /],
or [+, -, *, /] is not proceeded by a numeric  e.g."10-",
or [*, /] is not preceded by a numeric  e.g."-10" is valid, "*10" is not valid
throw an exception

I have the following code:

if (expression.match(/[^+\-*/\d.]/) ||
    expression.match(/[+-](?=[*/])/) ||
    expression.match(/[+\-*/]($|[^+\-.\d])/) ||
    expression.match(/(^|[^+\-.\d])[*/]/))
    throw errors.ExpressionParserError;

it works fine when the expressions are separated as above, but when I combine them with |(OR), it doesn't throw an exception anymore

if (expression.match(/[^+\-*/\d.] | [+-](?=[*/]) | [+\-*/]($|[^+\-.\d]) | (^|[^+\-.\d])[*/]/))
    throw errors.ExpressionParserError;

e.g. "d * 1" should fall in the first part of the expression [^+-*/\d.]

What did I miss here? Thanks.

Upvotes: 0

Views: 149

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074385

Two things:

  1. You have spaces around the |. Those spaces are significant.
  2. You may need to group the individual parts to ensure the alternation applies correctly (probably with non-capturing groups: (?:...)).

So for instance:

if (expression.match(/(?:[^+\-*/\d.])|(?:[+-](?=[*/]))|(?:[+\-*/]($|[^+\-.\d]))|(?:(^|[^+\-.\d])[*/])/))
// -------------------^^^-----------^^^--------------^^^----------------------^^^-------------------^
    throw errors.ExpressionParserError;

Side note: To just test for a match, use rex.test(str) rather than str.match(rex). No need to build a result array if your only goal is to test for a match.

Upvotes: 1

Related Questions