限制正则表达式中捕获的范围

Limiting captured range in RegEx expression

本文关键字:范围 正则表达式      更新时间:2023-09-26

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

想象一下,我有这样的文字:

chaff more chaff START PATTERN more chaff chaff more chaff START PATTERN juicy stuff juicy stuff juicy stuff END PATTERN chaff chaff START PATTERN more juicy stuff more juicy stuff END PATTERN

。我想要一个带有全局标志 (g) 的正则表达式来捕获多汁的东西。 具体来说,我希望第一场比赛是

START PATTERN juicy stuff juicy stuff juicy stuff END PATTERN

第二场比赛是

START PATTERN more juicy stuff more juicy stuff END PATTERN

美中不足的是第一个开始模式。 我花了一些时间在 regex101.com(对于那些不知道它的人来说,这是一个很棒的工具),这个不起作用:

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

它捕获了第二组("更多汁的东西"),但不是第一组。 我也尝试过各种消极展望的组合,但没有成功。

想法?

你需要一个温和的贪婪令牌:

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

请参阅正则表达式演示。

(?:(?!(?:START|END) PATTERN)[^])*被称为温和的贪婪代币,因为贪婪的*量词被负的展望所缓和。在展望中,我们列出了所有我们不想与尾随分隔符匹配的模式。

请注意,如果您计划将文字单词STARTEND匹配,则可以通过添加单词边界来增加精度:

'bSTART PATTERN'b(?:(?!'b(?:START|END) PATTERN)[^])*'bEND PATTERN

请注意,为了提高效率,我们可以展开它:

START PATTERN[^ES]*(?:S(?!TART PATTERN)[^ES]*|E(?!ND PATTERN)[^ES]*)*END PATTERN

观看其他演示