C# 验证松散定义的文件
我正在编写一个应用程序,它有一个定义非常松散的配置文件,可以在启动时读取。该文件易于解析,如下所示:C# 验证松散定义的文件,c#,file,parsing,C#,File,Parsing,我正在编写一个应用程序,它有一个定义非常松散的配置文件,可以在启动时读取。该文件易于解析,如下所示: tag1 = value1 tag2 = value2 tag3 = value3 tag4 = value4 标签和值是用户可能想要配置的信息。正如我前面所说的,该文件是松散定义的——也就是说,我不需要所有或任何字段,并且值不必按任何特定顺序排列。唯一真正的规则是它必须是上面的格式,任何我不认识的标签都会被忽略 在考虑上述约束进行解析时,有没有什么好方法可以检查文件是否有效?我正在用C语言开
tag1 = value1
tag2 = value2
tag3 = value3
tag4 = value4
标签和值是用户可能想要配置的信息。正如我前面所说的,该文件是松散定义的——也就是说,我不需要所有或任何字段,并且值不必按任何特定顺序排列。唯一真正的规则是它必须是上面的格式,任何我不认识的标签都会被忽略
在考虑上述约束进行解析时,有没有什么好方法可以检查文件是否有效?我正在用C语言开发.NET运行时的2.0.x版。谢谢。何必麻烦呢
你已经说你忽略了任何无效的东西
您可以在每一行上搜索“=”,但如果不需要花费代价就可以得到一个无效的文件,这似乎有点浪费
或者,您可以在顶部放置一个版本
#footype=1
然后,不管怎样,只要寻找一般良好的实践,因为当您稍微更改文件布局时,为什么要麻烦呢
你已经说你忽略了任何无效的东西
您可以在每一行上搜索“=”,但如果不需要花费代价就可以得到一个无效的文件,这似乎有点浪费
或者,您可以在顶部放置一个版本
#footype=1
然后,不管怎样,只要寻找一般良好的实践,因为当您稍微更改文件布局时,我建议使用正则表达式将文件解析到字典中。在读取文件之前,可以将所有支持的键的默认值添加到字典中。通过这种方式,您可以获得一个字典,其中包含独立于文件中找到的键的一致键集。在这种情况下,您可能会考虑添加支持的密钥列表,并在读取不支持的密钥的文件时检查此列表中的每个键。
const String fileName = @"foo.ini";
const String entryExpression = @"^\s*(?<key>[a-zA-Z][a-zA-Z0-9]*)\s*=" +
@"\s*(?<value>[a-zA-Z][a-zA-Z0-9]*)\s*$";
Dictionary<String,String> entries = new Dictionary<String, String>();
foreach (String line in File.ReadAllLines(fileName))
{
Match match = Regex.Match(line, entryExpression);
if (match.Success)
{
String key = match.Groups["key"].Value;
String value = match.Groups["value"].Value;
if (entries.ContainsKey(key))
{
Console.WriteLine("Overwriting the key '{0}'.", key);
}
entries[key] = value;
}
else
{
Console.WriteLine("Detected malformed entry '{0}'.", line);
}
}
我建议使用正则表达式将文件解析到字典中。在读取文件之前,可以将所有支持的键的默认值添加到字典中。通过这种方式,您可以获得一个字典,其中包含独立于文件中找到的键的一致键集。在这种情况下,您可能会考虑添加支持的密钥列表,并在读取不支持的密钥的文件时检查此列表中的每个键。
const String fileName = @"foo.ini";
const String entryExpression = @"^\s*(?<key>[a-zA-Z][a-zA-Z0-9]*)\s*=" +
@"\s*(?<value>[a-zA-Z][a-zA-Z0-9]*)\s*$";
Dictionary<String,String> entries = new Dictionary<String, String>();
foreach (String line in File.ReadAllLines(fileName))
{
Match match = Regex.Match(line, entryExpression);
if (match.Success)
{
String key = match.Groups["key"].Value;
String value = match.Groups["value"].Value;
if (entries.ContainsKey(key))
{
Console.WriteLine("Overwriting the key '{0}'.", key);
}
entries[key] = value;
}
else
{
Console.WriteLine("Detected malformed entry '{0}'.", line);
}
}
只是随机观察;这种格式也适用于python——因此,如果您想使用一些预先存在的代码并提供更大的灵活性,您可以嵌入IronPython并使用它来解析和执行配置文件。这将告诉您任何错误,如果成功,应通过查找使这些值可用
可能有点过头了,但实际上灵活的配置脚本作为DSL对python来说有点强;这种格式也适用于python——因此,如果您想使用一些预先存在的代码并提供更大的灵活性,您可以嵌入IronPython并使用它来解析和执行配置文件。这将告诉您任何错误,如果成功,应通过查找使这些值可用
可能有点过头了——但实际上,灵活的配置脚本作为DSL对于python来说是一个优势。如果第三方正在编写这些配置,我们只能假设,如果第三方正在验证这些配置,那么这并不完全明智;嵌入这样的编译器将有效地让他们进入他的应用程序的上下文并执行事情;这一切都取决于你对输入的信任程度。如果你愿意,你可以通过滥用app.config来做一些非常疯狂的事情。如果你能控制配置,你已经比你试图保护的系统强大了……如果第三方正在编写这些配置,我们只能假设,如果他正在验证这些配置,这不是完全明智的;嵌入这样的编译器将有效地让他们进入他的应用程序的上下文并执行事情;这一切都取决于你对输入的信任程度。如果你愿意,你可以通过滥用app.config来做一些非常疯狂的事情。如果你能控制配置,你已经比你试图保护的系统强大了……我喜欢你的风格:Regex++!我喜欢你的风格:Regex++!