仅捕获两个单词之间部分文本的正则表达式



我正在寻找一个为nodejs编写的正则表达式,它只能捕获以PASS开头的行中的文本!或失败!And出现在两个特定的单词之间。例子:

INFO! this line shouldn't be captured because it's before section121
[section120] section title1
Some noise
PASS! this line shouldn't captured either because it's before section121
[section121] section title2
more noise
FAIL! match1
a warning we wish to skip
more warnings
PASS! match2
FAIL! match3
[section122] section title3
noise
PASS! this shouldn't be captured because it appears after section122

这个输入的预期捕获是:

match1
match2
match3

这可以实现使用单个正则表达式吗?如果不是,一个解释为什么也会被接受作为一个答案。

我试着写了几个不同的正则表达式,但总是只捕获最后一行(match3):

section121][sS]*(?:PASS!|FAIL!)([sS]*)[section122

JavaScript支持向后看断言,您可以使用:

(?<=^[section121].*(?:n(?![sectiond+]).*)*n(?:PASS|FAIL)!).*

  • (?<=正向后看
    • ^字符串起始
    • [section121].*匹配[section121]和其余行
    • (?:n(?![sectiond+]).*)*匹配换行符,并重复匹配所有不以[section1+数字和]
    • 开头的行
    • n(?:PASS|FAIL)!匹配换行符和PASS!FAIL!
  • )关闭后视
  • .*匹配行其余部分(可选择匹配除换行符外的任何字符)

查看regex101演示

const regex = /(?<=^[section121].*(?:n(?![sectiond+]).*)*n(?:PASS|FAIL)!).*/gm;
const s = `INFO! this line shouldn't be captured because it's before section121
[section120] section title1
Some noise
PASS! this line shouldn't captured either because it's before section121
[section121] section title2
more noise
FAIL! match1
a warning we wish to skip
more warnings
PASS! match2
FAIL! match3
[section122] section title3
noise
PASS! this shouldn't be captured because it appears after section122`;
console.log(s.match(regex));

不支持向后看的替代方案,分两步:

const regex = /[section121].*(?:n(?![sectiond+]|(?:PASS|FAIL)!).*)*n(?:PASS|FAIL)!.*(?:n(?![sectiond+]).*)*/;
const s = `INFO! this line shouldn't be captured because it's before section121
[section120] section title1
Some noise
PASS! this line shouldn't captured either because it's before section121
[section121] section title2
more noise
FAIL! match1
a warning we wish to skip
more warnings
PASS! match2
FAIL! match3
[section122] section title3
noise
PASS! this shouldn't be captured because it appears after section122`;
const res = s.match(regex);
if (res) {
console.log(Array.from(res[0].matchAll(/^(?:PASS|FAIL)!(.*)/mg), m => m[1]))
}

最新更新