如何编写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
相关产品推荐
相关产品推荐

