sambha
sambha

Reputation: 1353

Regex to ignore parentheses while capturing within parentheses

I am parsing a file in javascript & have to capture some values. For example velocity values as below. Eg:

> "velocity(22)".match("\\(([^()]*)\\)");
[ '(22)', '22', index: 8, input: 'velocity(22)' ]

Above works fine and 22 gets captured in match[1]. Problem is when the values have units mentioned in parantheses. Eg:

> "velocity(22 (m/s))".match("\\(([^()]*)\\)");
[ '(m/s)', 'm/s', index: 12, input: 'velocity(22 (m/s))' ]

As seen above, m/s is captured instead of 22 (m/s)

What is the proper way to ignore parentheses when capturing within parentheses?

Upvotes: 1

Views: 2161

Answers (1)

Nick Abbott
Nick Abbott

Reputation: 374

Try this:

const num = "velocity(43)";
const units = "velocity(22 (m/s))";
const regex = /\(((\d+)(?: \((.+)\))?)\)/

console.log(num.match(regex));
console.log(units.match(regex));

Expression: /\(((\d+)(?: \((.+)\))?)\)/

We first match a parenthesis: (\() and capture 1 or more digits after it ((\d+)). This will be capture group 2. We then want to use a conditional to determine whether there are units. We use a non-capturing group ((?:ABC)) to group the characters without capturing the unneeded space. Inside we look for a space followed by any set of characters enclosed in parenthesis ((?: \((.+)\))). The set of characters is captured as capture group 3 and we define the non-capture group as optional with ?. We then detect a closing parenthesis \) and wrap the entire selection in capture group 1. If you wish to capture the enclosing parenthesis around the units also then just put the capture group around the escaped parenthesis character rather than inside.

Upvotes: 2

Related Questions