2016-01-19 110 views
3

捕獲範圍(注:是使用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)的RegEx來捕捉多汁的東西。具體而言,我想第一場比賽是

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)/? 

它抓住了第二組(「更水靈的東西」)但不是第一個。我也嘗試過各種負面預測組合,但沒有成功。

想法?

回答

2

你需要一個tempered greedy token

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

the regex demo

(?:(?!(?:START|END) PATTERN)[^])*被稱爲脾氣暴躁的標記,因爲貪婪的量詞使用了負向前視。在lookahead內部,我們列出了所有我們不希望匹配尾部分隔符的模式。

注意您可以通過添加單詞邊界,如果你打算匹配字面的話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

+0

@CasimiretHippolyte:謝謝。我注意到現在它可以吞噬更多沒有(儘管SND PATTERN不可能出現在字符串恕我直言:))。 –

+0

不,但'START PATTERN [^ ES] *(?: S(?!TART PATTERN)[^ S] *)*'可匹配「開始模式abcd Sefgh END PATTERN」。 –

+1

我看到,主要問題是表達式將無法匹配分隔符之間的*最小窗口*。 –