正则表达式:在由边界定义的分组中,只有当XX时才匹配。

3

背景:我正在尝试过滤一些日志,但我无法更改它们生成的方式。它们的格式基本上如下:

Some text here AAA
Some text here One
Some More text here
******
Some text here BBB
Some text here Two
Some More text here
******
Some text here CCC
Some text here Three
Some More text here
******
Some text here BBB
Some text here Four
Some More text here
******
Some text here BBB
Some text here Five
Some More text here
******

基本上,每个******都界定了一个新的日志事件
我正在尝试使用正则表达式匹配位于两个******之间并包含例如BBB的每个块。 (我知道第一个不以******开头,但是出于复杂性考虑,我可以不匹配它)
我尝试的方法基本上是“定义一个由******界定但中间没有另一个******的潜在匹配项”,但我不知道如何编写。 因此,在上述示例中,它将匹配包含Two、Four和Five的块。
我尝试了多种变体,例如:\*{6}(?!\*{6}).*BBB.*\*{6} 有什么建议吗? 编辑:我正在使用Notepad ++ / VisualStudio和Regex101.com中的PCRE(php)版本的正则表达式。

你使用的正则表达式工具是什么? - anubhava
我正在使用Notepad++,所以主要使用pcre,但我也在使用regex101.com(pcre)进行测试。如果需要的话,我也可以在VS中完成它。 - Tipx
^[^*]+\bB{3}\b[^*]+$ 是你真正要寻找的。 - Onyambu
3个回答

3

You may use this regex in PCRE:

(?:\A|\*{6})(?:(?!\*{6}).)*?BBB.*?(?=\R\*{6})

正则表达式演示

正则表达式详情:

  • (?:\A|\*{6}):匹配字符串开始或者 ******
  • (?:(?!\*{6}).)*?:匹配 0 或多个不在其前面有 ****** 的字符
  • BBB.*?:匹配 BBB 后面的 0 或多个字符
  • (?=\R\*{6}):使用先行断言,确保下一个位置是 ******

1
谢谢,太棒了!我已经将其适应到我的具体情况中,并且它表现得非常好。我会进行实验以确保我理解得很好,这样下次我就会知道了!:-D - Tipx
你需要小心 BBB,因为根据你编写的正则表达式,任何未被限定的 B 字符可能会被包含进来。 - Onyambu
如果BBB是一个完整的单词,则将BBB替换为\bBBB\b - anubhava

2

你需要什么:

^[^*]+\bB{3}\b[^*]+$

正则表达式演示

这里解释一下:

  • ^ 表示匹配行首
  • [^*]+ 匹配多个非 * 字符
  • \bB{3}\b 匹配三个边界为 B 的字符
  • [^*]+ 匹配多个非 * 字符
  • $ 表示匹配行尾

@UnbearableLightness,我不太确定是否需要捕获,因为原始发帖者已经声明要匹配“inbetween”的文本...这是我的担忧,虽然我们可以使用 ^[*]{6}[^*]+\bB{3}\b[^*]+ 来匹配六个星号。 - Onyambu

0

试试这个:(?<=\*{6}\s)(?=.*B{3})[^(?>\*{6})]+

它使用正向后瞻来匹配六个星号后面的空格(例如换行符,您也可以使用\n):(?<=\*{6}\s)

然后,它使用正向前瞻来确保以下文本包含BBB(?=.*B{3})

然后,它捕获一切直到下一个六个点,由于集合排除了六个星号的出现(因为我将其设置为原子(?>\*{6}))。

演示


3
它不是原子性的,你把 * 放到了否定类中,这使它停止匹配。如果块内没有 *,也可以使用 \*{6}[^*]*BBB[^*]*。此外,如果在不以 ****** 为前缀的第一个块中出现 BBB,它也不会匹配。 - bobble bubble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接