开发者

How can I parse a code string and build hierarchical array based on { and } in the string

I have a code-like string like the following:

a
{
    bcd
    {
        ef
        {
            gh
            {
                i
            }
            j
        }
    }
    k
    {
        lm开发者_如何学JAVAn
        {
            op
        }
        qr
        {
            st
        }
        uv
        {
            wx
        }
        y
    }
    z
}

I wish to parse this string such so that I can create a hierarchical array from this code where each tree gets created based on { and a tree ends at }.

The array would look like:

[
    "a",

    "{",

    [

        "bcd",

        "{",

        [
            "ef",

            "{",

            [
                "gh",

                "{",

                [
                    "i"
                ],

                "}",

                "j"
            ],

            "}"
        ],

        "}",

        "k",

        "{",

        [
            "lmn",
            "{",
            [
                "op"
            ],

            "}",
            "qr",

            "{",

            [
                "st"
            ],

            "}",

            "uv",

            "{",
            [
                "wx"
            ],

            "}",
            "y"
        ],

        "}",
        "z"
    ],

"}"
]

Can any one help me in getting an algo of this?

You can also pass me a code in any of these languages Java/C#/PHP/VB.NET/JavaScript/ActionScript.


If this is all you want to do you could write it like this (C#):

class Node
{
    public string Name { get; private set; }
    public IEnumerable<Node> Children { get; private set; }

    public Node(string name, IEnumerable<Node> children)
    {
        Name = name;
        Children = children;
    }
}

class Parser
{
    public Node Parse(string s)
    {
        return Parse(s.Split(new char[0], StringSplitOptions.RemoveEmptyEntries));
    }

    public Node Parse(IEnumerable<string> tokens)
    {
        using (var enumerator = tokens.GetEnumerator())
        {
            enumerator.MoveNext(); // move to first token
            return Parse(enumerator);
        }
    }

    Node Parse(IEnumerator<string> enumerator)
    {
        string name = enumerator.Current;
        enumerator.MoveNext();
        var children = new List<Node>();
        if (enumerator.Current == "{")
        {
            enumerator.MoveNext();
            while (enumerator.Current != "}")
            {
                children.Add(Parse(enumerator));
            }
            enumerator.MoveNext();
        }
        return new Node(name, children);
    }
}

This code doesn't check the return value of MoveNext(), which means it would produce weird results on invalid inputs (including the possibility of an infinite loop).

It also requires that the tokens are delimited by whitespace. So a string like a{b{c}} would be parsed as one node with the name a{b{c}}.

Creating a special type Node is much better than using weakly-typed array (even if you use weakly-typed language). And there is no need to include the braces in the result.

If you want to do something more complicated, I would recommend using some parser library.

If the string might be very long and you're reading it from a file or network, you might want to use some form of stream instead of ordinary string.


You are not really picky about the language, so I'm pretty curious why you want this. Here's some code that should do what you want in C#:

public static object[] ParseSpecial(string s)
{
    string dummy = "";
    Stack<List<object>> result = new Stack<List<object>>();
    result.Push(new List<object>());
    foreach (char character in s)
    {
        switch (character)
        {
            case '{':
                if (dummy.Length > 0)
                    result.Peek().Add(dummy);
                dummy = "";

                result.Peek().Add("{");
                result.Push(new List<object>());
                break;

            case '}':
                if (dummy.Length > 0)
                    result.Peek().Add(dummy);
                dummy = "";

                List<object> temp = result.Pop();
                result.Peek().Add(temp.ToArray());
                result.Peek().Add("}");
                break;

            default:
                dummy += character;
                break;
        }
    }

    if (dummy.Length > 0)
        result.Peek().Add(dummy);

    return result.Peek().ToArray();
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜