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.
