简体   繁体   中英

JavaScript Regex to match any words within nested square brackets?

I'm trying to find a way to use regex to make text italic inside of square [] brackets, inclusive of nested square brackets, but not the brackets themselves. So far the best I've come up with is:

text = text.replace(/(\[+)([^\[\]]+)(]+)/g, '$1<span style="font-style: italic;">$2</span>$3');

however that fails in the case of nested brackets, something like:

[test1] test2 ([[readonly ][optionality ][argumentType ]argumentName[ = defaultValue]]...) [test3] test4

Should parse to:

[ test1 ] test2 ([[ readonly ][ optionality ][ argumentType ] argumentName [ = defaultValue ]]...) [ test3 ] test4

But instead the above regex produces:

[ test1 ] test2 ([[ readonly ][ optionality ][ argumentType ]argumentName[ = defaultValue ]]...) [ test3 ] test4

(with the text argumentName normal instead of italics)

One approach is to match each bracket group and replace each word within that group inside of the replace callback:

string.replace(/(\[(?:\[[^\]]*\]|[^\[\]]*)*\])/g, function (match) {
  return match.replace(/(\w+)/g, '*$1*');
});

Example Snippet:

 var string = "[test1] test2 ([[readonly ][optionality ][argumentType ]argumentName[ = defaultValue]]...) [test3] test4"; var result = string.replace(/(\\[(?:\\[[^\\]]*\\]|[^\\[\\]]*)*\\])/g, function (match) { return match.replace(/(\\w+)/g, '*$1*'); }); document.body.textContent = result; 

Explanation :

The expression /(\\[(?:\\[[^\\]]*\\]|[^\\[\\]])*\\])/ will match each bracket group in your case by utilizing an alternation:

(            # Capturing group
\[           # Opening bracket
(?:          # Non-capturing group
\[[^\]]*\]   # Match nested brackets that don't contain other brackets
|            # Alternation.. or:
[^\[\]]*     # Match non-bracket characters
)*           # Close the non-capturing group and match it zero or more times
\]           # Closing bracket
)            # Close the capturing group

Then in the replace callback, each word is wrapped with the italics:

match.replace(/(\w+)/g, '*$1*');

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