Avraham
Avraham

Reputation: 607

Regex: matching nested parentheses

Consider the following string:

(first group) (second group) (third group)hello example (words(more words) here) something

The desired matches would be:

(first group)
(second group)
(third group)
(words(more words) here)

I've tried to build a regex as follows:

/\(.*?\)/g

But it matches the following:

(first group)
(second group)
(third group)
(words(more words)

Any ideas?

Upvotes: 1

Views: 1225

Answers (3)

wp78de
wp78de

Reputation: 18950

Since this needs to be done in JavaScript, we have two options:

a) specify a pattern with a fixed nesting depth (this seems to be case here):

\((?:[^()]|\([^()]*\))*\)

const regex = /\((?:[^()]|\([^()]*\))*\)/g;
const str = `(first group) (econd group) (third group)hello example (words(more words) here) something`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Or use XRegexp (or a similar library) that implements recursive matching:

const str = `(first group) (econd group) (third group)hello example (words(more words) here) something`;
console.log(XRegExp.matchRecursive(str, '\\(', '\\)', 'g'));
<script src="https://cdn.jsdelivr.net/npm/[email protected]/xregexp-all.js"></script>

Upvotes: 2

Can you please try out the below regular expression which uses recursion

\(([^()]|(?R))*\)

Upvotes: 0

stunner.agk
stunner.agk

Reputation: 36

Maybe this could work in your case. \((?:[^()]|\([^()]+\))+\).

Side note: Not too proud of how I did this.

Upvotes: 0

Related Questions