(注意:以下是使用 javascript 风格的 RegExen,其中 . 不匹配换行符,但 [^] 匹配。)
假设我有这段文字:
chaff 更多 chaff START PATTERN 更多 chaff
chaff more chaff 开始模式多汁的东西
多汁的东西 多汁的东西 结束模式 谷壳
谷壳开始模式更多多汁的东西更多
多汁的东西结束模式
...我想要一个带有全局标志 (g) 的 RegEx 来捕获有趣的东西。具体来说,我希望第一场比赛是
开始模式多汁的东西
多汁的东西 多汁的东西 END PATTERN
第二场比赛是
START PATTERN 更多有趣的东西
多汁的东西结束模式
美中不足的是第一个 START 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)[^])*
被称为缓和贪婪标记,因为贪婪 *
量词是消极的前瞻性调和。在 lookahead 中,我们列出了所有不想与尾随定界符匹配的模式。
请注意,如果您打算匹配文字单词 START
和 END
,您可以通过添加单词边界来提高精度:
\bSTART PATTERN\b(?:(?!\b(?:START|END) PATTERN)[^])*\bEND PATTERN
请注意,为了提高效率,我们可以展开它:
START PATTERN[^ES]*(?:S(?!TART PATTERN)[^ES]*|E(?!ND PATTERN)[^ES]*)*END PATTERN
参见 another demo
关于javascript - 限制 RegEx 表达式中的捕获范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34880673/