解析包含数组的字符串

dij*_*tra 9 c# string list

我想将包含递归字符串数组的字符串转换为深度为一的数组.

例:

StringToArray("[a, b, [c, [d, e]], f, [g, h], i]") == ["a", "b", "[c, [d, e]]", "f", "[g, h]", "i"]
Run Code Online (Sandbox Code Playgroud)

看起来很简单.但是,我来自功能背景,我不熟悉.NET Framework标准库,所以每次(我从头开始像3次)我最终只是简单的丑陋代码.我最近的实施就在这里.如你所见,这很丑陋.

那么,C#的做法是什么?

Sco*_*pey 6

@ojlovecd使用正则表达式有一个很好的答案.
然而,他的答案过于复杂,所以这是我类似的,更简单的答案.

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;
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,您将看到StringToArray("[a, b, [c, [d, e]], f, [g, h], i]")将返回以下数组:["a", "b", "[c, [d, e]]", "f", "[g, h]", "i"].

有关我用于匹配平衡括号的平衡组的更多信息,请查看Microsoft的文档.

更新:
根据评论,如果您还想平衡报价,这里有一个可能的修改.(注意,在C#中,它"被转义为"")我还添加了模式的描述以帮助澄清它:

    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);
Run Code Online (Sandbox Code Playgroud)