在无序的日志文件中搜索

时间:2011-08-30 20:38:29

标签: c# regex search

我工作的地方有一个日志文件,其中包含以下行:

  

31201007061308000000161639030001

这是这样读的:

  

31 |年(4)|月(4)|天(2)|小时(2)|分钟(2)| 000000 |设施(3)|徽章(5)| 0001

所以每条记录应该有一条线,但是会发生这样的事情:

31201007192000000000161206930004
31201007192001000000161353900004
31201031201007192004000000161204690004
31201007192004000000090140470004
31201007192005000000090148140004
3120100719200500031201007191515000000161597180001
31201007191700000000161203490001
31201007191700000000161203490001
31201007191700000000161202830001
31201007191700000000

这是因为应该读取该文件的软件,有时它会遗漏一些新的记录,而负责人会将旧记录复制到文件的末尾。所以基本上就是因为人为错误。

当记录未保存在DB中时,我必须搜索该文件。起初我只做了一个遍历文件中每个记录的cicle,但它真的很慢,上面提到的问题使它变慢了。我现在采用的方法是使用正则表达式,就像这样:

//Starts Reader
StreamReader reader = new StreamReader(path);
string fileLine = reader.ReadLine();
while (!reader.EndOfStream)
{
  //Regex Matcher
  Regex rx = new Regex(@"31\d\d\d\d\d\d\d\d\d\d\d\d000000161\d\d\d\d\d0001");

  //Looks for all valid lines
  MatchCollection matches = rx.Matches(fileLine);

  //Compares each match against what we are looking for
  foreach (Match m in matches)
  {
    string s = m.Value;
    compareLine(date, badge, s);
  }

  reader.ReadLine();
}
reader.Close(); //Closes reader

我的问题是:搜索文件的好方法是什么?我应该先订购/清洁吗?

2 个答案:

答案 0 :(得分:2)

您可能最好遵循以下步骤:

  • 将每一行解析为一个对象。结构应该适合这些行。包括DateTime对象以及任何其他相关字段。如果你稍微清理它,可以使用Regex轻松完成。使用捕获组和转发器。对于一年,您可以使用(\d{4})获取行中的4个数字,而不是\d\d\d\d
  • 创建一个List<MyStruct>,将每行保存为对象。
  • 使用LINQ搜索列表,例如:

    var searchResults = from eachEntry in MyList
                        where eachEntry.Date > DateTime.Now
                        and eachEntry.facility.Contains("003")
                        select eachEntry;

此外,将此行添加到您的正则表达式,它会加快速度,如果只是几毫秒:

MatchCollection matches = rx.Matches(fileLine, RegexOptions.Compiled);

答案 1 :(得分:0)

如果您(提前)知道您正在寻找哪个条目,即I.e。你完全知道你正在寻找的日期,设施和批次,你根本不需要解析数据。生成期望的字符串并进行简单的字符串搜索而不是使用正则表达式可能会更快:

string expectedValue = getExpectedValue(date, badge);
// expectedValue = "31201007192000000000161206930004"
foreach (string line in lines)
{
    if (line.IndexOf(expectedValue) >= 0)
    {
          // record found
    }
}

如果您只对该文件包含您的ID感兴趣,可以将整个文件读入单个字符串并按

进行搜索
string completeFile = GetFileContents(file);
if (completeFile.IndexOf(expectedValue) >= 0)
{
     // record found
}