You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Regex匹配指定模式直至该模式下一次出现?

正则表达式匹配连续日志条目(直至下一个相同模式出现)

嘿,我来帮你搞定这个日志匹配的正则问题!看起来你需要把连续的日志条目拆分开——每条都以时间戳+日志级别(比如2018-03-20 23:28:47 INFO)开头,内容可能包含换行、特殊字符,直到下一个同样的日志开头或者文本结尾。

核心正则表达式

下面这个正则可以完美适配你的需求,支持多行内容匹配:

(?s)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)).*?(?=\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)|$)

正则各部分解释

让我拆解一下每个部分的作用:

  • (?s):开启单行模式,让.可以匹配换行符,这样日志里的多行内容也能被完整捕获
  • (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)):
    • 捕获日志的开头标识:匹配YYYY-MM-DD HH:MM:SS格式的时间戳,加上INFO或DEBUG级别
    • (?:...)是非捕获组,用来限制级别可选范围,但不会单独把级别作为一个匹配组返回
  • .*?:非贪婪匹配任意字符(包括换行),这里一定要用非贪婪模式,不然会直接匹配到最后一条日志的结尾
  • (?=\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)|$):
    • 正向预查断言,匹配下一个日志开头或者文本结尾
    • 这是零宽度匹配,不会被包含在结果里,确保每条日志刚好截止到下一条开头的前一个字符

实际使用示例(Python)

如果你用Python处理日志,可以参考这段代码:

import re

# 你的原始日志数据
log_content = """2018-03-20 23:28:47 INFO 这是一条信息示例(可包含换行符的多行内容)
2018-03-20 23:28:47 INFO 这是一条信息示例(可包含换行符的多行内容)
2018-03-20 23:28:47 DEBUG 这是一条调试示例(可包含换行符的多行内容){ 'x':1, 'y':2, 'z':3, 'w':4 } 
2018-03-20 23:28:47 INFO 这是一条信息示例(可包含换行符的多行内容)
2018-03-20 23:28:47 DEBUG 这是一条调试示例(可包含换行符的多行内容..."""

# 编译正则表达式
pattern = re.compile(r'(?s)(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)).*?(?=\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)|$)')

# 提取所有日志条目
log_entries = pattern.findall(log_content)

# 打印结果
for i, entry in enumerate(log_entries, 1):
    print(f"第{i}条日志:")
    print(entry.strip())
    print("-" * 60)

扩展说明

  • 如果你的日志还有其他级别(比如WARN、ERROR),只需要在非捕获组里添加即可:(?:INFO|DEBUG|WARN|ERROR)
  • 如果需要保留整个日志内容(包括开头标识后面的所有内容),可以把捕获组调整一下,或者直接去掉捕获组,匹配整个条目:(?s)\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG).*?(?=\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:INFO|DEBUG)|$)

内容的提问来源于stack exchange,提问作者Aditya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:43:40