我有一个我要解析并加载到数据库中的日志文件。我正在努力解决它的最佳方法。
日志文件的格式为类别:信息
Case Number: CASE01
User ID: JOSM
Software: Microsoft Word
Date Started: 21-01-2010
Date Ended: 22-01-2010
事实上,日志文件中还有其他的碎片和碎片,这意味着信息并不总是存在于同一条线上。我也只想要信息,而不是类别。
到目前为止,我已经尝试将它全部放入由\ r \ n分隔的数组中,但我必须知道我想要的信息的索引,以便一致地检索它,并且这会改变。我也试过通过StreamReader提供它并说
if (line.Contains("Case Number"))
{
tbReport.AppendText("Case Number: " + line.Remove(0, 13) + "\r\n");
}
它为我提供了我想要的信息,但却很难做到。
我觉得我最好离开数组路径,但我可以做一些关于如何在数组中搜索该类别的指导,然后解析信息。
一旦我能准确地解析它,将它添加到数据库中应该是相当直接的。因为这是我第一次尝试这个,所以我会对任何有关此问题的最佳方法的提示或指导感兴趣。
感谢。
答案 0 :(得分:2)
这将为您提供包含所有键/值对的集合。
List<KeyValuePair> items = new List<KeyValuePair>();
var line = reader.ReadLine();
while (line != null)
{
int pos = line.IndexOf(':');
items.Add(new KeyValuePair(line.Substring(0, pos), line.Substring(pos+1));
line = reader.ReadLine();
}
如果您有一个包含所有可能名称作为属性的日志类,则可以改为使用反射:
class LogEntry
{
public string CaseNumber { get; set; }
public string User { get; set; }
public string Software{ get; set; }
public string DateStarted { get; set; }
public string DateEnded { get; set; }
}
List<LogEntry> items = new List<LogEntry>();
var line = reader.ReadLine();
var currentEntry = new LogEntry();
while (line != null)
{
if (line == "") //empty line = new log entry. Change to your delimiter.
{
items.Add(currentEntry);
currentEntry = new LogEntry();
}
int pos = line.IndexOf(':');
var name = line.Substring(0, pos).Replace(" ", string.Empty);
var value = line.Substring(pos+1);
var pi = entry.GetType().GetProperty(name);
pi.SetValue(entry, value, null);
line = reader.ReadLine();
}
请注意,我没有测试过代码(只是在这里直接编写)。您必须添加错误检查等。最后一种选择并不是很有效,但应该做得好。
答案 1 :(得分:0)
听起来像是RegExp的好候选案例:
http://www.regular-expressions.info/dotnet.html
它们不是太容易学习,但是一旦你掌握了基本的理解,它们就不会被这些任务所打败。
答案 2 :(得分:0)
这不是一个简单的答案,但您是否可以使用正则表达式来解析信息?
正则表达式有点像硬核,但是它们可以很容易地解析高级文件。
所以在我能看到的内容中,它就像:
如果一条线以A-Z开头,那么(a-z或A-Z或0-9或空格)从零到多次,然后是a:然后是空格,然后是值。
所以如果你为它做一个正则表达式(如果你等了一会儿,我会尝试为你制作一个),那么你可以测试每一行。如果它匹配,那么我们也可以使用正则表达式来取出最后一部分和“密钥”。如果它不匹配,那么我们只需将它附加到最后一个键。
要注意它并非完全万无一失,因为新系列可以这样开始,但我认为它是我们能做的最好的事情。
这里承诺的是正则表达式的起点:
^(?'key'[A-Z][a-z,A-Z,0-9,\s]+):\s(?'value'.+)
因此,为了尝试告诉它的作用,我们需要浏览每个部分:
我实际上认为你可以只拿整个字符串,然后匹配一个:
RegEx.Matches(或类似的东西),并循环遍历它们。
然后只需将match.Groups [“key”]和match.Groups [“value”]放入您的数组中。 (对不起,我没有Visual Studio方便测试它)