Description
You can do this by combining some recursive logic around a regular expression
This regular expression will match open and close brackets nested in three layers, like {a{b{c}}}{{{d}e}f}
\{((?:\{(?:\{.*?\}|.)*?\}|.)*?)\}

The dotted area is the main search in which this search is nested inside itself on as many layers as you need.
In the following example, I just run regex for most of your examples. Combine this regular expression with a foreach loop that will take each group 1 and grab all the non-open brackets from the beginning of the current line ^[^{]* , and then recursively pass the rest of the line back through the regular expression above to commit the value in the next group brackets, then grab all non-closed brackets from the end of the string [^}]*$ .
Sample text
{a} {a:b} {a:{b}} {a:{b:c}} {a}{b} {a}{b}{c} {a{b{c}}}{{{d}e}f}
C # .NET Code Example:
This C # .Net example only shows how a regular expression works. See how group 1 gets the inner text from the outer group of most brackets. Each external text in brackets was divided into its own array position and the corresponding external brackets where they were deleted.
using System; using System.Text.RegularExpressions; namespace myapp { class Class1 { static void Main(string[] args) { String sourcestring = "sample text above"; Regex re = new Regex(@"\{((?:\{(?:\{.*?\}|.)*?\}|.)*?)\}",RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline); MatchCollection mc = re.Matches(sourcestring); int mIdx=0; foreach (Match m in mc) { for (int gIdx = 0; gIdx < m.Groups.Count; gIdx++) { Console.WriteLine("[{0}][{1}] = {2}", mIdx, re.GetGroupNames()[gIdx], m.Groups[gIdx].Value); } mIdx++; } } } } $matches Array: ( [0] => Array ( [0] => {a} [1] => {a:b} [2] => {a:{b}} [3] => {a:{b:c}} [4] => {a} [5] => {b} [6] => {a} [7] => {b} [8] => {c} [9] => {a{b{c}}} [10] => {{{d}e}f} ) [1] => Array ( [0] => a [1] => a:b [2] => a:{b} [3] => a:{b:c} [4] => a [5] => b [6] => a [7] => b [8] => c [9] => a{b{c}} [10] => {{d}e}f ) )
Renouncement
This expression will only work on the third level of recursion. The outer text must be processed separately. The .net regex engine offers recursion counting and can support N levels. As written here, this expression may not handle g capture as expected in {a:{b}g{h}i} .
source share