首页 > 解决方案 > 如何从此日志输出中找到最里面的失败模式

问题描述

鉴于此日志记录输出。我想匹配path/to/*.command所有失败的命令。在这种情况下,它是第三个和第四个命令。

    Starting.. path/to/first.command
      Some Text..
    Done

    Starting.. other/path/to/second.command
      Some Other Text..
    Done

    Starting.. other/path/to/third.command
      Some Text..
    Fail

    Starting.. other/path/to/forth.command
      Some Other Text..
    Fail

这就是我想出的Starting.. (.+\.command)[\s\S]+?Fail

但这还不够好。不情愿的量词与最内部的匹配 third.command 不匹配。但相反,它与封闭的 first.command 匹配(就正则表达式而言,这是正确的,但不受欢迎)

此处演示:https ://regex101.com/r/fl3eaz/1

标签: javascriptregex

解决方案


[\s\S]+将贪婪地匹配任何字符序列,包括换行符,但您只想搜索到遇到Failor的点。Done因为这些Some Text行总是正好一行长,所以通过(在命令之后)匹配单个 [\s\S](换行符),然后是一行字符,然后是另一个[\s\S]+(换行符),然后是Fail.

const input = `
    Starting.. path/to/first.command
      Some Text..
    Done

    Starting.. other/path/to/second.command
      Some Other Text..
    Done

    Starting.. other/path/to/third.command
      Some Text..
    Fail

    Starting.. other/path/to/forth.command
      Some Other Text..
    Fail
    `;
const re = /Starting\.\. (.+\.command)[\s\S].+[\s\S] +Fail/g;
let match;
while (match = re.exec(input)) {
  console.log(match[1]);
}

如果您使用(更新的,较少支持的)lookbehind 会更简单:

const input = `
    Starting.. path/to/first.command
      Some Text..
    Done

    Starting.. other/path/to/second.command
      Some Other Text..
    Done

    Starting.. other/path/to/third.command
      Some Text..
    Fail

    Starting.. other/path/to/forth.command
      Some Other Text..
    Fail
    `;
const re = /(?<=Starting\.\. +).+\.command(?=[\s\S].+[\s\S] +Fail)/g;
console.log(input.match(re));


推荐阅读