Home > Mobile >  Can I create a regular expression in JavaScript which validates specific math formula - letters and
Can I create a regular expression in JavaScript which validates specific math formula - letters and

Time:07-11

I want to validate an input field with regular expression in JavaScript, which should validate the following cases:

Valid:

A and B and C and D
(A or B) and C
(A or B or C) and D
(A or B or C or D) and E
A and (B or C) and D
A and (B or C) or (C and D)
A or (B and C)
(A and B) or (C and D)

Invalid:

A and B and C and 
(A or B and C
(A or B or C) and D or
(A or B or C or D and E
A and or (B or C) and D
A and (B or (C and D)))
A (B and C)
(A and B) or C and D)
(A and B or C and D)

Basically I need some letter from A-Z(only upper-case) followed by "and" or "or" and unlimited brackets, but the opening brackets amount should match the amount of closing ones. Also after an opening bracket I should have to be able to insert only A-Z upper-case and after a closing bracket "and", "or" or A-Z upper-case should also be valid. Nested brackets shouldn't also be valid.

I've came up with this solution, but it's only validating A-Z upper-case, "and" and "or" words and brackets, so all invalid cases provided are matching my regex.

/^[A-Z(]?[A-Z]| |and|or|[(]|[A-Z]|[)]/gm

CodePudding user response:

A JS regular expression could be:

^(?!\([^()]*\)$|.*([()])[^()]*(?=\1)|[^()]*[()](?:[^()]*[()][^()]*[()])*[^()]*$|.*\([A-Z]\))\(?[A-Z](?: (?:and|or) \(?[A-Z]\)?)*$

See an online demo


  • ^ - Start-line anchor;
  • (?! - Open a negative lookahead with alternations;
    • \([^()]*\)$ - Avoid a match with an operning paranthesis, 0 characters other than paranthesis, and a closing paranthesis. Or;
    • .*([()])[^()]*(?=\1) - 0 Character upto a opening/closing paranthesis in a 1st capture group followed by 0 characters other than paranthesis upto a backreference to 1st group. Or;
    • [^()]*[()](?:[^()]*[()][^()]*[()])*[^()]*$ - A check for unbalanced paranthesis. The pattern will enfore there is a multiple of two paranthesis if any has been used. Or;
    • .*\([A-Z]\) - Test for 0 characters followed by opening, capital letter and direct closing, to avoid (A)-like input;
  • \(?[A-Z] - Match an optional paranthesis followed by A-Z (to allow a single letter to be a valid match too);
  • (?: (?:and|or) \(?[A-Z]\)?)* - Open a non-capture group to match a space, a nested non-capture group to match and|or followed by another space, an optional operning paranthesis, another capital letter and an optional closing paranthesis. This grouping is matches 0 times;
  • $ - End-line anchor.

CodePudding user response:

Without nested brackets, this is easy. One disjunctive clause of the conjunctive normal form is

[A-Z]( or [A-Z])*

With parenthesis required around clauses using or:

[A-Z]|\([A-Z]( or [A-Z])*\)

The whole formula would then be

([A-Z]|\([A-Z]( or [A-Z])*\))( and ([A-Z]|\([A-Z]( or [A-Z])*\)))*
  • Related