@ojlovecd has a good answer, using Regular Expressions.
However, his answer is overly complicated, so here's my similar, simpler answer.
public string[] StringToArray(string input) {
var pattern = new Regex(@"
\[
(?:
\s*
(?<results>(?:
(?(open) [^\[\]]+ | [^\[\],]+ )
|(?<open>\[)
|(?<-open>\])
)+)
(?(open)(?!))
,?
)*
\]
", RegexOptions.IgnorePatternWhitespace);
// Find the first match:
var result = pattern.Match(input);
if (result.Success) {
// Extract the captured values:
var captures = result.Groups["results"].Captures.Cast<Capture>().Select(c => c.Value).ToArray();
return captures;
}
// Not a match
return null;
}
Using this code, you will see that StringToArray("[a, b, [c, [d, e]], f, [g, h], i]")
will return the following array: ["a", "b", "[c, [d, e]]", "f", "[g, h]", "i"]
.
For more information on the balanced groups that I used for matching balanced braces, take a look at Microsoft's documentation.
Update:
As per the comments, if you want to also balance quotes, here's a possible modification. (Note that in C# the "
is escaped as ""
) I also added descriptions of the pattern to help clarify it:
var pattern = new Regex(@"
\[
(?:
\s*
(?<results>(?: # Capture everything into 'results'
(?(open) # If 'open' Then
[^\[\]]+ # Capture everything but brackets
| # Else (not open):
(?: # Capture either:
[^\[\],'""]+ # Unimportant characters
| # Or
['""][^'""]*?['""] # Anything between quotes
)
) # End If
|(?<open>\[) # Open bracket
|(?<-open>\]) # Close bracket
)+)
(?(open)(?!)) # Fail while there's an unbalanced 'open'
,?
)*
\]
", RegexOptions.IgnorePatternWhitespace);