我想解析一个配置文件,如下所示:

[KEY:Value]     
    [SUBKEY:SubValue]

现在我开始了 StreamReader, ,将行转换为字符数组,当我认为必须有更好的方法时。所以我请求你,谦虚的读者,帮助我。

一个限制是它必须在 Linux/Mono 环境中工作(确切地说是 1.2.6)。我没有最新的 2.0 版本(Mono),因此尝试将语言功能限制为 C# 2.0 或 C# 1.0。

有帮助吗?

解决方案

我考虑过,但我不打算使用 XML。我将手动编写这些内容,而手动编辑 XML 让我的大脑受伤。:')

你看过吗 YAML?

您可以享受 XML 的好处,而无需承受所有的痛苦和磨难。它在 ruby​​ 社区中广泛用于配置文件、预先准备的数据库数据等

这是一个例子

customer:
  name: Orion
  age: 26
  addresses:
    - type: Work
      number: 12
      street: Bob Street
    - type: Home
      number: 15
      street: Secret Road

似乎有一个 C# 库在这里, ,我没有亲自使用过,但是YAML非常简单,所以“这有多难?” :-)

我想说最好发明自己的临时格式(并处理解析器错误)

其他提示

前几天我正在研究几乎这个问题: 本文 字符串标记化正是您所需要的。您需要将令牌定义为:

@"(?&ltlevel>\s) | " +
@"(?&ltterm>[^:\s]) | " +
@"(?&ltseparator>:)"

这篇文章很好地解释了这一点。从那里你就可以开始吃掉你认为合适的代币。

专家提示:为 LL(1) 解析器 (读:简单),令牌不能共享前缀。如果你有 abc 作为一个令牌,你不能拥有 ace 作为令牌

笔记:文章缺少|字符在示例中,只需将它们扔进去即可。

另一个用于 .NET 的 YAML 库 正在开发中。目前它支持读取 YAML 流,并已在 Windows 和 Mono 上进行了测试。目前正在实施写入支持。

使用库几乎总是比创建自己的库更好。以下是“哦,我永远不需要那个/我没有想到那个”要点的快速列表,这些要点最终会在以后困扰您:

  • 转义字符。如果你想要一个:在键中还是在值中?
  • 转义转义字符。
  • 统一码
  • 制表符和空格的混合(请参阅 Python 的空白敏感语法的问题)
  • 处理不同的返回字符格式
  • 处理语法错误报告

正如其他人所建议的那样,YAML 看起来是您最好的选择。

您还可以使用堆栈,并使用推/弹出算法。这与开始/结束标签匹配。

public string check()
    {
        ArrayList tags = getTags();


        int stackSize = tags.Count;

        Stack stack = new Stack(stackSize);

        foreach (string tag in tags)
        {
            if (!tag.Contains('/'))
            {
                stack.push(tag);
            }
            else
            {
                if (!stack.isEmpty())
                {
                    string startTag = stack.pop();
                    startTag = startTag.Substring(1, startTag.Length - 1);
                    string endTag = tag.Substring(2, tag.Length - 2);
                    if (!startTag.Equals(endTag))
                    {
                        return "Fout: geen matchende eindtag";
                    }
                }
                else
                {
                    return "Fout: geen matchende openeningstag";
                }
            }
        }

        if (!stack.isEmpty())
        {
            return "Fout: geen matchende eindtag";
        }            
        return "Xml is valid";
    }

您也许可以进行调整,以便可以读取文件的内容。正则表达式也是一个好主意。

在我看来,您最好使用基于 XML 的配置文件,因为已经有 .NET 类可以相对轻松地为您读取和存储信息。有什么理由认为这是不可能的吗?

@伯纳德: 确实,手动编辑 XML 很乏味,但是您所呈现的结构看起来已经与 XML 非常相似。

那么是的,那里有一个很好的方法。

@Gishu

实际上,一旦我适应了转义字符,我的正则表达式的运行速度就比我手写的自上而下的递归解析器稍慢,并且没有嵌套(将子项链接到它们的父项)和错误报告手写解析器。

正则表达式的编写速度稍快一些(尽管我确实有一些手动解析器的经验),但没有良好的错误报告。一旦你添加了这一点,它就会变得稍微困难​​和更长。

我还发现手写的解析器更容易理解其意图。例如,这里是代码片段:

private static Node ParseNode(TextReader reader)
{
    Node node = new Node();
    int indentation = ParseWhitespace(reader);
    Expect(reader, '[');
    node.Key = ParseTerminatedString(reader, ':');
    node.Value = ParseTerminatedString(reader, ']');
}

无论持久格式如何,使用正则表达式将是最快的解析方法。在 ruby​​ 中,可能只有几行代码。

\[KEY:(.*)\] 
\[SUBKEY:(.*)\]

这两个将为您提供第一组中的值和子值。查看 MSDN,了解如何将正则表达式与字符串进行匹配。

这是每个人的猫咪都应该拥有的东西。正则表达式出现之前的日子看起来就像冰河时代。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top