(注意:以下使用的是JavaScript风格的RegExen,其中。与换行符不匹配,但[^]匹配。)

想象一下我有这段文字:
chaff more chaff START PATTERN more chaffchaff more chaff START PATTERN juicy stuffjuicy stuff juicy stuff END PATTERN chaffchaff START PATTERN more juicy stuff morejuicy stuff END PATTERN
...,我想要一个带有全局标志(g)的RegEx来捕获多汁的东西。具体来说,我希望第一场比赛是
START PATTERN juicy stuffjuicy stuff juicy stuff END PATTERN
第二场比赛是
START PATTERN more juicy stuff morejuicy stuff END PATTERN
美中不足的是第一个开始模式。我已经在regex101.com(对那些不了解它的人来说是一个了不起的工具)上度过了一段时间,但是这个方法不起作用:

/(?:START PATTERN[^]+)?(START PATTERN[^]+END PATTERN)/?

它捕获了第二组(“多汁的东西”),但没有捕获第一组。我还尝试过各种否定先行组合,但均未成功。

有想法吗?

最佳答案

您需要一个tempered greedy token:

START PATTERN(?:(?!(?:START|END) PATTERN)[^])*END PATTERN
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

参见the regex demo
(?:(?!(?:START|END) PATTERN)[^])*称为经过调节的贪婪 token ,因为贪婪的*量词以负前瞻方式进行调节。在前瞻内部,我们列出了所有我们不希望与尾随定界符匹配的模式。

请注意,如果您计划匹配文字单词STARTEND,则可以通过添加单词边界来提高精度:
\bSTART PATTERN\b(?:(?!\b(?:START|END) PATTERN)[^])*\bEND PATTERN

请注意,为提高效率,我们可以展开它:
START PATTERN[^ES]*(?:S(?!TART PATTERN)[^ES]*|E(?!ND PATTERN)[^ES]*)*END PATTERN

参见another demo

07-27 21:52