如何将复杂字符串解析为数据结构

时间:2013-01-07 17:47:25

标签: c# string parsing

我需要帮助理解将复杂字符串解析为Tree数据结构的最简单方法。 我试图找出如何使用C#解析此字符串。

以下是此字符串的示例:

[[Le[[filet|tartare]]|La grillade]]de gateau|Une [[portion|part]] de gateau

[[...]]是一个集合和|是集合

中的分隔符

例如,我需要获取

    Set 1
       Set 1-1
           Le
           Set 1-1-1
              filet
              tartare
           La grillade
    Set 2
       Une 
       Set 2-1
          portion
          part 
       de gateau

1 个答案:

答案 0 :(得分:0)

using System;
using System.Collections.Generic;
using System.IO;

class Tree
{
    int currentIndent;

    public Tree(string s)
    {
        this.Trees = new List<Tree>();
        this.Values = new List<string>();
        this.currentIndent = 0;

        if (s == null)
            throw new ArgumentNullException();

        if (s == "")
            return;

        int beginPos = 0;
        while (beginPos < s.Length)
        {
            if (s[beginPos] == '[')
            {
                string res = "";
                uint openedBraceCount = 1;
                uint closedBraceCount = 0;
                int index = beginPos + 1;
                while (openedBraceCount != closedBraceCount)
                {
                    if (s[index] == '[')
                        openedBraceCount++;
                    if (s[index] == ']')
                        closedBraceCount++;
                    res += s[index];
                    index++;
                }
                beginPos = index;
                this.Trees.Add(new Tree(res.Substring(0, res.Length - 1)));
            }
            else
            {
                int endPos = beginPos + 1;
                while (endPos < s.Length && s[endPos] != '[')
                    endPos++;
                string[] values = s.Substring(beginPos, endPos - beginPos).Split('|');
                for (int i = 0; i < values.Length; i++)
                    values[i] = values[i].Trim();
                this.Values.AddRange(values);
                beginPos = endPos;
            }
        }
    }

    public void Print(TextWriter writer, int indent)
    {
        this.currentIndent = indent;
        Print(writer, 0, this);
        this.currentIndent = 0;
    }

    private void Print(TextWriter writer, int indent, Tree tree)
    {
        foreach (string value in tree.Values)
            writer.WriteLine("{0}{1}", new string(' ', indent), value);
        foreach (Tree t in tree.Trees)
            Print(writer, currentIndent + indent, t);
    }

    public List<Tree> Trees { get; set; }

    public List<string> Values { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        string s = "[[Le[[filet|tartare]]|La grillade]]de gateau|Une [[portion|part]] de gateau";
        var tree = new Tree(s);
        tree.Print(Console.Out, 2);
    }
}