如何用单个正则表达式提取两种格式initcall日志的指定信息?
合并initcall日志匹配正则的解决方案
现有Python代码通过两个正则表达式匹配两种不同格式的initcall日志,可成功提取ts(时间戳)、func(函数名)、ret(返回值)、val(耗时)字段,当前输出符合预期。现希望将两个正则合并为一个,简化逻辑、提升代码可读性。
原代码
import re content = """ [ 1.765989] initcall init_module.cfi_jt+0x0/0x8 [altmode_glink] returned 0 after 379 usecs [ 0.001873] initcall selinux_init+0x0/0x1f8 returned 0 after 85 usecs """ for line in content.split("\n"): m = re.search("\[\s+(?P<ts>[\d.]+)\] initcall init_module.*\[(?P<func>[^ ]+)\] returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs",line) if m: ts = m['ts'] func = m['func'] ret = m['ret'] val = m['val'] print(ts,func,ret,val) else: m = re.search("\[\s+(?P<ts>[\d.]+)\] initcall (?P<func>[^ ]+)\+.*? returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs",line) if m: ts = m['ts'] func = m['func'] ret = m['ret'] val = m['val'] print(ts,func,ret,val)
原输出
1.765989 altmode_glink 0 379 0.001873 selinux_init 0 85
合并正则后的解决方案
可以通过正则的分支结构(|)将两种格式的匹配逻辑合并,针对func字段的两种出现位置做统一处理。合并后的正则会共用后续的匹配逻辑,避免重复代码。
修改后的完整代码
import re content = """ [ 1.765989] initcall init_module.cfi_jt+0x0/0x8 [altmode_glink] returned 0 after 379 usecs [ 0.001873] initcall selinux_init+0x0/0x1f8 returned 0 after 85 usecs """ # 合并后的正则表达式 pattern = re.compile(r"\[\s+(?P<ts>[\d.]+)\] initcall (?:init_module.*\[(?P<func>[^ ]+)\]|(?P<func>[^ ]+)\+.*?) returned (?P<ret>[\d-]+) after (?P<val>[\d-]+) usecs") for line in content.split("\n"): m = pattern.search(line) if m: ts = m['ts'] func = m['func'] ret = m['ret'] val = m['val'] print(ts, func, ret, val)
关键说明
- 使用
(?:...)创建非捕获分组,包裹两种格式的分支逻辑,避免生成多余的捕获组 - 分支1:
init_module.*\[(?P<func>[^ ]+)\]匹配第一种格式中包裹在[]内的函数名 - 分支2:
(?P<func>[^ ]+)\+.*?匹配第二种格式中直接跟在initcall后的函数名 - 提前编译正则表达式(
re.compile)可提升多次匹配的执行效率
内容的提问来源于stack exchange,提问作者lucky1928
相关产品推荐
相关产品推荐

