限制RegEx表达式中捕获的范围

时间:2016-01-19 15:28:52

标签: javascript regex

(注意:以下是使用javascript风格的RegExen,其中。与newline不匹配,但[^]确实如此。)

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

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)的RegEx来捕获多汁的东西。具体来说,我希望第一场比赛是

START PATTERN juicy stuff juicy stuff juicy stuff END PATTERN

和第二场比赛是

START PATTERN more juicy stuff more juicy stuff END PATTERN

美中不足的是第一个START PATTERN。我花了一些时间在regex101.com(对于那些不了解它的人来说这是一个很棒的工具),而且这个不起作用:

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

它捕获了第二组(“更多汁的东西”)但不是第一组。我也尝试过各种负向前瞻的组合,但没有成功。

想法?

1 个答案:

答案 0 :(得分:2)

您需要tempered greedy token

$date = new DateTime("2016-01-17");
$week = $date->format("W");
echo "Weeknummer: $week";   

请参阅the regex demo

START PATTERN(?:(?!(?:START|END) PATTERN)[^])*END PATTERN ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 被称为驯化的贪婪令牌,因为贪婪的(?:(?!(?:START|END) PATTERN)[^])*量词使用负前瞻来调节。在前瞻中,我们列出了我们不希望与尾随分隔符匹配的所有模式。

请注意,如果您计划匹配文字*START,则可以通过添加字边界来添加更多精度:

END

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

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

请参阅another demo