Home > Software engineering >  regex replace only outer brackets of nested parenthesis
regex replace only outer brackets of nested parenthesis

Time:01-18

Looking to preserve inner nested brackets when replacing brackets. If possible to make many nested layers work that would be great, if not just nested once is fine.

(if money>5 and (times   total_cash >266))[something]
(if times   total_cash >266)[something]

{if money>5 and (times   total_cash >266)}[something]
{if times   total_cash >266}[something]

A naive attempt doesn't seem to work that well:

str.replace(/\(if(.*?)\)]/gi, '{if $1}')

CodePudding user response:

for zero level of nesting:

str.replace(/\(if\s*([^()]*)\)/gi, '{if $1}')

for one level (or less):

str.replace(/\(if\s*([^()]*(?:\([^()]*\)[^()]*)*)\)/gi, '{if $1}')

for two levels (or less):

str.replace(/\(if\s*([^()]*(?:\([^()]*(?:\([^()]*\)[^()]*)*\)[^()]*)*)\)/gi, '{if $1}')

etc. This method becomes quickly limited.

Javascript regexes don't have features like recursive patterns (perl, pcre), or a counter system like in .net languages. That's why, the best option is to build a state machine to count the number of opening and closing parenthesis (note that you can use a regex to split your string to interesting parts to do it, for example: str.split(/(\bif\b|[()])/i)).


Note that [^()]*(?:\([^()]*\)[^()]*)* is an optimized way to write: (?:[^()]|\([^()]*\))* (that is shorter but inefficient). This subpattern is unrolled.

  •  Tags:  
  • Related