使用正则表达式匹配两个特定单词之间的所有内容

时间:2010-08-27 15:48:09

标签: c# ruby regex text-parsing logfiles

我正在尝试使用正则表达式解析Oracle跟踪文件。我选择的语言是C#,但我选择使用Ruby进行练习以熟悉它。

日志文件有些可预测。大多数行(99.8%,具体)符合以下模式:

# [Timestamp]                  [Thread]  [Event]   [Message]
# TIME:2010/08/25-12:00:01:945 TID: a2c  (VERSION) Managed Assembly version: 2.102.2.20
# TIME:2010/08/25-14:00:02:398 TID:1a60  OpsSqlPrepare2(): SELECT * FROM MyTable
line_regex = /^TIME:(\S+)\s+TID:\s*(\S+)\s+(\S+)\s+(.*)$/

然而,在日志中的一些地方,由于某种原因,有很多复杂的问题需要跨越几行:

Screenshot

有关这些条目的两点要注意的是,它们似乎会在日志文件中导致某种损坏,因为它们以不可打印的字符结束,然后突然下一个条目从同一行开始。

由于这显然排除了以每行为基础捕获数据,我认为下一个最佳选择是匹配单词“TIME:”与“TIME:”的下一个实例或文件末尾之间的所有内容。我不知道如何使用正则表达式表达这一点。

有更有效的方法吗?我需要解析的日志文件将超过1.5GB。我的目的是规范化行,并删除不必要的行,最后将它们作为行插入数据库中进行查询。

谢谢!

2 个答案:

答案 0 :(得分:2)

在“TIME:”和“TIME:”字符串或文件末尾之间匹配潜在多行数据的正则表达式是:

/^TIME:(.+?)(?=TIME:|\z)/im

另一方面,正如James提到的那样,为“TIME:”子字符串进行标记,或者查找“\ r \ nTIME:”的子字符串位置(在第一个“TIME:”条目之后,取决于换行符格式)证明是一种更好的方法。

答案 1 :(得分:1)

这可能更适合做这个老派,即一次读一行你的文件...从第一个'TIME'开始,并连接你的行直到你到达下一个'TIME'...你可以使用正则表达式过滤掉你不想要的任何行。

我不能和Ruby说话;在C#中它当然是StreamReader,它可以帮助您处理文件大小。