在C#中解析日志文件的最佳方法

时间:2010-11-03 08:58:11

标签: c# text-parsing

我有以下日志文​​件:

START:SOME_STRING
BL:2
LK:3
LH:5
end
START:SOME_STRING
BL:5
LK:6
LH:6
end

哪个有多个START: - >内部结构。是否有更好的“非草率”方式解析此文件而不是逐行读取并使用SPLIT?

3 个答案:

答案 0 :(得分:2)

你可以尝试形式化你的ini文件的语法,以及你的一些解析器生成器。有关详细信息,请参阅this question

请注意,对于这样一个简单的语法而言,手动解析可能更容易:-P

class IniEntry
{
    public int BL;
    public int LK;
    public int LH;
    IniEntry Clone() { return new IniEntry { BL = BL, LK = LK, LH = LH }; }
}

IEnumerable<IniEntry> Parse()
{
    IniEntry ie = new IniEntry();
    while (ParseEntry(out ie))
        yield return ie.Clone();
}

bool ParseEntry(out IniEntry ie)
{
    ie = new IniEntry();
    return ParseStart(ie) &&
               ParseBL(ie) &&
               ParseLK(ie) &&
               ParseLH(ie) &&
               ParseEnd(ie);
}

bool ParseStart(IniEntry ie)
{
    string dummy;
    return ParseLine("START", out dummy);
}

bool ParseBL(IniEntry ie)
{
    string BL;
    return ParseLine("BL", out BL) && int.TryParse(BL, out ie.BL);
}

bool ParseLK(IniEntry ie)
{
    string LK;
    return ParseLine("LK", out LK) && int.TryParse(LK, out ie.LK);
}

bool ParseLH(IniEntry ie)
{
    string LH;
    return ParseLine("LH", out LH) && string.TryParse(LH, out ie.LH);
}

bool ParseLine(string key, out string value)
{
    string line = GetNextLine();
    var parts = line.Split(":");
    if (parts.Count != 2) return false;
    if (parts[0] != key) return false;
    value = parts[1];
}

答案 1 :(得分:0)

这是while循环和状态机的理想选择。 使用这种方法,您甚至可以使用更少的内存,并且比使用string.split()

具有更高的性能

答案 2 :(得分:0)

如果确定START / END总是匹配,(道歉,我的C#很尴尬,那么简单的英语):

Read the whole file with System.IO.ReadToEnd
Parse the whole thing in one go with a regular expression
Iterate over regex results

正则表达式类似于“(START:([^ $] +)$ BL :( [^ $] +)$ LK:([^ $] +)$ LH:([^ $] +) $ end $)+“,在我的头顶,你需要根据参数BL / LK等的发生方式进行验证/调整