'Working with regex and parentheses to return 3 groups: operand1/operator/operand2
I'm trying to use a Regex in JavaScript which matches a string and returns 3 groups: operand1, operator, and operand2. For example dissecting an exponent clause:
const EXPONENT_REGEX = /(\S+)\s*([\^])\s*(\S+)/
const inpStr = '5 ^ 2 + 10 * 2'
inpStr.match(EXPONENT_REGEX)
// Returns: ['5 ^ 2', '5', '^', '2']
// i.e. [Matched Clause, Operand1, Operator, Operand2]
When trying a similar approach to handle parentheses clauses however, and possible nested parentheses- I've been unable to find the right arrangement of escape square brackets and parentheses for grouping to return me those 3 values. Consider:
const PARENTHESES_REGEX = /\([^\(\)]*\)/
const inpStr = '5 ^ 2 + 10 * (10 - (4 + (2 + 1))'
inpStr.match(PARENTHESES_REGEX)
Currently this does not return any groups, but does match '(2 + 1)'. How might I structure this to return those same 3 groups as the first example? Here that would look like:
['2 + 1', '2', '+', '1']
Solution 1:[1]
Use
const PARENTHESES_REGEX = /\((-?\d*\.?\d+)\s*([-+\/*])\s*(\d*\.?\d+)\)/g
const inpStr = '5 ^ 2 + 10 * (10 - (4 + (2 + 1))'
console.log([...inpStr.matchAll(PARENTHESES_REGEX)])
EXPLANATION
--------------------------------------------------------------------------------
\( '('
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
-? '-' (optional (matching the most amount
possible))
--------------------------------------------------------------------------------
\d* digits (0-9) (0 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
\.? '.' (optional (matching the most amount
possible))
--------------------------------------------------------------------------------
\d+ digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
\s* whitespace (\n, \r, \t, \f, and " ") (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
( group and capture to \2:
--------------------------------------------------------------------------------
[-+\/*] any character of: '-', '+', '\/', '*'
--------------------------------------------------------------------------------
) end of \2
--------------------------------------------------------------------------------
\s* whitespace (\n, \r, \t, \f, and " ") (0 or
more times (matching the most amount
possible))
--------------------------------------------------------------------------------
( group and capture to \3:
--------------------------------------------------------------------------------
\d* digits (0-9) (0 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
\.? '.' (optional (matching the most amount
possible))
--------------------------------------------------------------------------------
\d+ digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
) end of \3
--------------------------------------------------------------------------------
\) ')'
Results: (4) ['(2 + 1)', '2', '+', '1', index: 24, input: '5 ^ 2 + 10 * (10 - (4 + (2 + 1))', groups: undefined]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ryszard Czech |
