零宽断言配合非贪婪捕获可精准定位关键词位置并提取可控上下文,预编译正则提升效率,结合re.DOTALL和re.MULTILINE支持跨行与按行匹配,结构清晰且鲁棒性强。

直接用 零宽断言 + 非贪婪捕获 就能稳准快地定位关键词及其周边内容,不用提取整段再切片,避免误截或漏截。
用先行/后行断言锁定位置,不吞字符
关键词本身不一定要出现在结果里,关键是“在哪出现”。零宽断言只判断条件,不占用匹配位置:
- (?:匹配 ERROR 后面紧跟的一个单词(如 "Connection"),但不把 "ERROR " 包进去
- \d+(?=ms):提取所有后面紧跟着 "ms" 的数字(如 "245ms" 中的 245)
- (?:匹配独立的 4 位数字(排除在 12345 里的 1234),靠负向断言卡边界
搭配非贪婪捕获,提取可控范围的上下文
想拿关键词前后各 10 个字符?用 .{0,10} + ? 控制长度和懒惰性:
-
(.{0,15})error(.{0,15}):捕获 error 前后最多 15 字符,
.*?会贪心跨段,.{0,15}更安全 - 加括号分组后,
match.group(1)是左上下文,group(2)是右上下文,结构清晰 - 若需保留换行,开启
re.DOTALL,让.能匹配 \n
结合行锚点与多行模式,按行抓上下文
日志类文本常以行为单位,用 ^ 和 $ 配合 re.MULTILINE 更自然:
- ^(.*?ERROR.*?$)(?:\n^.*?$){0,2}:匹配含 ERROR 的行,再往后取最多两行(作为后续上下文)
- (?:^.*?$\n){1,2}^.*?FATAL.*?$:往前找 1–2 行,再匹配含 FATAL 的当前行
- 用
re.finditer()遍历,每个 Match 对象调.span()可算出行号,方便定位
预编译 + 标志位,提升重复使用的稳定性
复杂模式别每次现写,提前编译并固定行为:
-
ctx_pat = re.compile(r"(?i)(.{0,20})timeout(.{0,20})", re.DOTALL)—— 忽略大小写、支持换行 - 多次调用
ctx_pat.findall(text)比反复re.findall(...)快且一致 - 若上下文含空格/制表符多,用
\s*替代空格,比硬写空格更鲁棒

















