使用正则表达式解析多行控制台输出的技术问题
解决多行日志分割的正则表达式问题
嘿,我完全懂你的困扰——你的当前正则只能处理单行日志,碰到那种带列表的多行条目就抓不全,对吧?别着急,咱们来调整一下正则,让它能完美捕获每条日志,包括多行的内容。
问题根源
你原来用的/\[(.*?)\](.*)/g有两个小问题:
- 默认情况下,正则里的
.是不匹配换行符的,所以碰到日志里的换行就会停止匹配,抓不到后面的列表内容; (.*)是贪婪匹配,但即使改成非贪婪,没有处理换行的话还是没用。
解决方案
我们需要让正则能跨多行匹配,并且在遇到下一个[My Custom Exe]标识时停止。这里分两种情况给你方案:
方案1:支持DotAll模式的环境(比如现代JavaScript、Python 3.6+等)
使用s标志(DotAll)让.匹配包括换行在内的所有字符,再结合正向预查来确定每条日志的结束位置:
/\[My Custom Exe\](.*?)(?=\[My Custom Exe\]|$)/gs
拆解一下这个正则的各个部分:
\[My Custom Exe\]:精确匹配每条日志的开头标识(比起原来的(.*?),直接写死更精准,避免匹配其他带括号的内容);(.*?):非贪婪匹配任意字符(包括换行,因为有s标志);(?=\[My Custom Exe\]|$):正向预查,确保匹配到下一个[My Custom Exe]或者字符串结尾就停止,不会把下一条日志的开头包含进来;gs:g是全局匹配(抓所有日志条目),s是DotAll模式(让.匹配换行)。
方案2:不支持DotAll模式的环境
如果你的正则环境不支持s标志(比如旧版JS或某些语言),可以用[\s\S]代替.——它匹配所有空白和非空白字符,自然也包括换行:
/\[My Custom Exe\]([\s\S]*?)(?=\[My Custom Exe\]|$)/g
示例代码(JavaScript)
用你提供的日志来测试一下:
const logContent = `[My Custom Exe][2018-05-24 11:03:01] Starting Process [My Custom Exe][2018-05-24 11:03:01] Getting config [My Custom Exe][2018-05-24 11:03:02] Beginning operation [My Custom Exe][2018-05-24 11:03:02] Could not complete this operation, invalid inputs [My Custom Exe][2018-05-24 11:03:02] Available inputs are: - 1: Mode 1 - 2: Mode 2 - 3: Mode 3 - 4: Mode 4 - 5: Mode 5 [My Custom Exe][2018-05-24 11:03:02] Exiting Program`; // 使用方案1的正则 const regex = /\[My Custom Exe\](.*?)(?=\[My Custom Exe\]|$)/gs; // 提取匹配结果并去除前后空白 const logEntries = [...logContent.matchAll(regex)].map(match => match[1].trim()); console.log(logEntries.length); // 输出6,正好是你要的数量 console.log(logEntries[4]); // 会输出那条带列表的完整多行内容
这样处理后,就能完美把每条日志(包括多行的那条)分割成数组的单个元素啦。
内容的提问来源于stack exchange,提问作者Bodungus
相关产品推荐
相关产品推荐

