简体   繁体   中英

regex replace only outer brackets of nested parenthesis

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}')

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM