Taking this previous regex and modifying the code a little...
string msg= "(((a) or (b) or (c)) and ((d) or (e)) and ((!f) or (!g)))";
var charSetOccurences = new Regex(@"\(((?:[^()]|(?<o>\()|(?<-o>\)))+(?(o)(?!)))\)");
var charSetMatches = charSetOccurences.Matches(msg);
foreach (Match mainMatch in charSetMatches)
{
var sets = charSetOccurences.Matches(mainMatch.Groups[1].Value);
foreach (Match match in sets)
{
Console.WriteLine(match.Groups[0].Value);
}
}
The first regex is being used to get the contents of the outermost paren.
The same regex is then used to get the individual sets within the 'larger' content. You get this as output:
((a) or (b) or (c))
((d) or (e))
((!f) or (!g))
If you want to remove the outer parens, just change the innermost line:
Console.WriteLine(match.Groups[0].Value);
to
Console.WriteLine(match.Groups[1].Value);
To get:
(a) or (b) or (c)
(d) or (e)
(!f) or (!g)
I trust you can take it from here.