【问题标题】:Parsing tree in C#C#中的解析树
【发布时间】:2011-02-10 15:03:07
【问题描述】:

我有一个像这样的 [文本] 树:

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

树2

+---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);
    }
}

【问题讨论】:

  • 我认为你的树模棱两可——或者我误解了某些部分。 Step3 在 \-- 之后是 step4,但是当 step2.1 发生同样的情况时,我们得到 step2.2?
  • 树中的名称是相关的,将它们视为随机文件夹名称..
  • 如果你的例子中有step_2.3,前面会是+---还是\---
  • 贾斯汀,如果有 step_2.3,那么它将以 \--- 开头,而 step_2.2 将以 +--- 开头

标签: c# parsing tree


【解决方案1】:

如果您的文本如此简单(只是+---\--- 前面有一系列|),那么正则表达式可能超出您的需要(以及是什么绊倒了您)。

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);
    }
}

【讨论】:

  • 好的,正在测试它,当树看起来像 tree2 时它会刹车,然后 step1.2 仍然作为 step-1 子添加..
  • @value: Tree-2 看起来格式不正确(至少基于我使用的规则编写的)。 +---step_2 不应该是 \---step_2,因为它是其父节点下的最后一个节点?
  • @Adam,是的,对此感到抱歉。只是树中的一个错字,与问题无关。
  • @value:我明白了;看看我刚刚所做的编辑是否解决了这个问题。我现在不在VS前面,所以我不能自己测试它,但它是一个相当小的变化。
  • @Adam,您所做的更改破坏了第一个树示例的代码。它不会将 step_2.1 和 step_2.1 添加为 step2 的子节点。
【解决方案2】:

Regex 在这里看起来绝对没有必要,因为您的标记语言中的符号(毕竟就是这样)既是静态的又很少。也就是说:尽管标签名称可能会有所不同,但在尝试将它们解析为相关部分时,您需要寻找的标记永远不会是 +---\---. 之外的任何其他标记。

来自question I answered yesterday:“正则表达式对于在很大程度上未知的大海捞针中描述一整类针非常有用,但它们不是用于非常静态格式的输入的正确工具。”

字符串操作是您解析它所需要的,特别是因为您正在处理一种递归标记语言,can't be fully understood by regex anyway。我还建议创建一个树型数据结构来存储数据(令人惊讶的是,doesn't seem to be included in the framework 除非他们在 2.0 之后添加它)。

顺便说一句,您上面的正则表达式似乎有一个不必要的\,但这在大多数正则表达式风格中并不重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 2013-09-07
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多