Парсинг дерева в C # - PullRequest
       28

Парсинг дерева в C #

3 голосов
/ 10 февраля 2011

У меня есть [текстовое] дерево, подобное этому:

+---step-1
|   +---step_2
|   |   +---step3
|   |   \---step4
|   +---step_2.1
|   \---step_2.2
+---step1.2

Tree2

+---step-1
|   \---step_2
|   |   +---step3
|   |   \---step4
+---step1.2

Это всего лишь маленький пример, дерево может быть глубже и с большим количеством детей и т. Д..

Прямо сейчас я делаю это:

for (int i = 0; i < cmdOutList.Count; i++)
{
    string s = cmdOutList[i];
    String value = Regex.Match(s, @"(?<=\---).*").Value;
    value = value.Replace("\r", "");
    if (s[1].ToString() == "-")
    {
        DirectoryNode p = new DirectoryNode { Name = value };
        //p.AddChild(f);
        directoryList.Add(p);
    }
    else
    {
        DirectoryNode f = new DirectoryNode { Name = value };
        directoryList[i - 1].AddChild(f);
        directoryList.Add(f);
    }
}

Но это не обрабатывает "step_2.1" и "step_2.2"

Я думаюЯ делаю это совершенно неправильно, может быть, кто-то может помочь мне с этим.

РЕДАКТИРОВАТЬ :

Вот класс DirectoryNode, чтобы сделать это немного большеясно ..

public class DirectoryNode
{
    public DirectoryNode()
    {
        this.Children = new List<DirectoryNode>();
    }
    public DirectoryNode ParentObject { get; set; }
    public string Name;
    public List<DirectoryNode> Children { get; set; }

    public void AddChild(DirectoryNode child)
    {
        child.ParentObject = this;
        this.Children.Add(child);
    }
}

Ответы [ 2 ]

3 голосов
/ 10 февраля 2011

Если ваш текст такой простой (просто +--- или \---, перед которым стоит серия |), тогда регулярное выражение может быть больше, чем вам нужно (и что вас сбивает с толку).

DirectoryNode currentParent = null;
DirectoryNode current = null;
int lastStartIndex = 0;

foreach(string temp in cmdOutList)
{
    string line = temp;

    int startIndex = Math.Max(line.IndexOf("+"), line.IndexOf(@"\");

    line = line.Substring(startIndex);

    if(startIndex > lastStartIndex) 
    {
        currentParent = current;
    }
    else if(startIndex < lastStartIndex)
    {
        for(int i = 0; i < (lastStartIndex - startIndex) / 4; i++)
        {
            if(currentParent == null) break;

            currentParent = currentParent.ParentObject;
        }
    }

    lastStartIndex = startIndex;

    current = new DirectoryNode() { Name = line.Substring(4) };

    if(currentParent != null)
    {
        currentParent.AddChild(current);
    }
    else
    {
        directoryList.Add(current);
    }
}
0 голосов
/ 10 февраля 2011

Регулярное выражение определенно выглядит здесь ненужным, поскольку символы на вашем языке разметки (в конце концов, это то, чем он является) являются статическими и их немного.То есть: хотя названия меток могут различаться, токены, которые нужно искать при попытке их разбить на соответствующие фрагменты, никогда не будут чем-то иным, чем +---, \--- и ..

Из вопроса , на который я ответил вчера : «Регулярные выражения чрезвычайно полезны для описания целого класса игл в неизвестном стоге сена, но они не являются подходящим инструментом для ввода, который находится вочень статичный формат. "

Манипуляции со строками - это то, что вам нужно для синтаксического анализа, особенно если вы работаете с рекурсивным языком разметки, который в любом случае не может быть полностью понят регулярным выражением .Я бы также предложил создать древовидную структуру данных для хранения данных (которая, к удивлению, , похоже, не включена в структуру , если они не добавили ее после 2.0).

Кроме того, в вашем приведенном выше регулярном выражении, похоже, содержится лишний \, но это не имеет значения в большинстве разновидностей регулярных выражений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...