我想解析配置文件sorta的事情,如下:
[KEY:Value]
[SUBKEY:SubValue]
现在我开始使用StreamReader
,将行转换为字符数组,当我认为必须有更好的方法时。所以我请谦虚的读者帮助我。
一个限制是它必须在Linux / Mono环境中工作(确切地说是1.2.6)。我没有最新的2.0版本(Mono),因此请尝试将语言功能限制为C#2.0或C#1.0。
答案 0 :(得分:12)
我考虑过了,但我不打算使用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# library here,我没有亲自使用过,但是yaml非常简单,所以“它有多难?” : - )
我认为最好发明自己的ad-hoc格式(并处理解析器错误)
答案 1 :(得分:4)
前几天我几乎看到了这个确切的问题:关于字符串标记化的this article正是你所需要的。您需要将令牌定义为:
@"(?<level>\s) | " +
@"(?<term>[^:\s]) | " +
@"(?<separator>:)"
这篇文章很好地解释了它。从那里你就可以开始吃你认为合适的代币了。
Protip:对于LL(1) parser(读取:简单),令牌不能共享前缀。如果您有abc
作为令牌,则不能将ace
作为令牌
注意:文章缺少|在其示例中的字符,只需将它们扔进去。
答案 2 :(得分:1)
使用库几乎总是最好自己动手。这是一个快速列表,“哦,我永远不需要那个/我没有考虑到这一点”,这些点最终会让你在以后咬你:
像其他人所说,YAML看起来是你最好的选择。
答案 3 :(得分:1)
正在开发another YAML library for .NET。现在它支持读取YAML流,并已在Windows和Mono上进行过测试。目前正在实施写支持。
答案 4 :(得分:0)
在我看来,您最好使用基于XML的配置文件,因为已经有.NET类可以相对容易地为您读取和存储信息。有没有理由这是不可能的?
@Bernard:手工编辑XML确实很乏味,但您所呈现的结构看起来与XML非常相似。
然后是的,那里有一个很好的方法。
答案 5 :(得分:0)
您也可以使用堆栈,并使用推/弹算法。这个匹配开/关标签。
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";
}
您可以调整,以便阅读文件内容。正则表达式也是一个好主意。
答案 6 :(得分:0)
@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, ']');
}
答案 7 :(得分:-1)
无论持久化格式如何,使用Regex都是最快的解析方式。 在ruby中,它可能只是几行代码。
\[KEY:(.*)\]
\[SUBKEY:(.*)\]
这两个可以获得第一组中的Value和SubValue。查看MSDN如何将正则表达式与字符串匹配。
这是每个人都应该拥有的小猫。前正规革命时期似乎是冰河时代。