Python正则表达式减少模式中的冗余?

2024-05-26 17:42:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我们正在编写一个Python脚本来解析应用程序日志文件。在

大多数日志文件将遵循类似的格式:

09:05:00.342344343 [DEBUG] [SOME_APPLICATION] [SOME_FUNCTION] Lorem ipsum dolor sic amet

我们有各种正则表达式来解析通过的不同类型的日志行,并将相关字段分为Python正则表达式组(时间戳、日志级别、原始应用程序/函数以及有效负载中的字段)。在

我把这些正则表达式都存储在dict中:

^{pr2}$

然而,显然每个模式之间有相当多的重叠——用于提取时间戳、日志级别等的正则表达式是共享的。在

有没有办法消除这种冗余?你能从一个通用模板中构建出不同的正则表达式字符串吗?在

扩展名-我循环文件中的行,然后对每一行,循环每个编译的正则表达式。在此基础上,有不同的函数来处理每种情况—例如,如果我们检测到某种类型的消息,我们可能需要先搜索三行以找到另一行,然后从中提取一个字段。在

我也在考虑在foobar_patterns dict中存储一个函数,然后当我们找到一个匹配项时,执行它。在

这是Python式的做事方式吗?在

干杯, 维克托


Tags: 文件函数debug脚本应用程序类型application格式
3条回答

在构建复杂的正则表达式时,我经常使用“语法”方法。例如,“你先把语法定义为:

logfile_grammar = {
    'spaces':  '\s+',
    'mname':   '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)',
    'month':   r'\d\d',
    'day':     r'\d\d',
    'year':    r'\d{4}',
    'date':    '(?P<date>($year-$month-$day)|($day $spaces $mname $spaces $year))',
    'payload': '(?P<payload>.+)',
    # more stuff
    'line':    '$date $spaces $payload'
}

如您所见,右边的$xxx表示左边的键(符号)。然后将此语法转换为正则表达式:

^{pr2}$

现在,line_regex是一个可以处理任何可能的日志行的正则表达式。在

MONTH = r'(?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'
DAY = r'(?P<day>\d{2})'
TIME = r'(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})'
SPC = r'\s'
HOST = r'(?<host>\w+)'
PREFIX = SPC.join(MONTH, DAY, TIME, HOST)
foobar_patterns = {
    'pattern1': re.compile(PREFIX + r'\s(?<payload>blahbla hbla h blah)'),
    'pattern2': re.compile(PREFIX + r'\s(?<payload>bla h blahbla hblah)'),
}

你考虑过两次解析吗?E、 g.第一步提取timestamplevelApplicationFunction,然后解析有效负载?您可能需要做一些缓存,可能首先构建一个已解析日志对象的列表,然后评估指定的日志消息(这样可以更容易地跳过前面的3行(如您所述,可能是必要的),而无需解析两次行)

或者,您可以使用字符串合并:

伪代码:

basePattern = "\[\w+\]\[\w+\]\[\w+\]"
foobar_patterns {
 'payloadPattern1':'asdf',
 'payloadPattern2':'asdff',
}
for patternKey in foobar_patterns:
    foobar_patterns[patternKey] = re.compile(basePattern + foobar_patterns[paternKey])

相关问题 更多 >

    热门问题