2015-05-09 42 views
4

我想編寫一個正則表達式來匹配文本,如果它只包含一次字符串。該文本只能包含<scr>一次。這裏有一些例子:正則表達式匹配文本,如果它只包含一個字符串一次

hello-<scr>Keephello-endofstring // ok; <scr>發生一次

test-<scr>bla<scr>bla-end //不好; <scr>發生2次

hello-Keephello-end //不好; <scr>不會發生

我試圖用以下正則表達式:

((?:(?<!<scr>).)*<scr>(?:(?!<scr>).)*) 

第一負回顧後確保<scr>不會發生。
<scr>必須遵循。
在此之後,負向前視確保不會再有更多的<scr>

它不起作用。
我想知道這可以用正則表達式來完成嗎? (有解釋)

回答

2

要檢查文本包含一些子只有一次,你需要檢查匹配不構成<scr>,再搭配<scr>,並使用負先行檢查所有的字符,如果沒有<scr>進一步,並且消耗所有字符。此外,線/串邊界^/$是必須的:

^(?:(?!<scr>).)*<scr>(?!.*<scr>).*$ 

demo

說明

  • ^ - 啓動線(如m多選項設置爲ON)
  • (?:(?!<scr>).)* - 與每個字符匹配的非捕獲組(不換行 - 對於這一點,你還需要添加s單線選項)未前面有<scr>
  • <scr> - 我們的文字<scr>
  • (?!.*<scr>) - 負回顧後檢查,我們沒有<scr>更多
  • .*$ - 子模式將其餘字符與行尾相匹配。
+1

Thanx,這個工程。 – deemon

+1

基於來自@stribizhev的正則表達式,這是匹配n個出現的''的代碼:^((?:(?! )。)*(?: (?:(?! )。)* ){2,2})$。第一部分'(?:(?! )。)*'不允許''。第二部分'(?:(?:(?! )。)*){2,2}'表示:''後面跟着一個文本,不包含''。第二部分重複2次。這個正則表達式匹配一個正文兩次包含''的文本。 – deemon

+1

您可以使用「{2}」來代替「{2,2}」。此外,不需要在整個表達式中添加圓括號,因爲您始終可以通過組0訪問整個匹配。這只是一個提示,如何使此正則表達式更「清潔」。 –

0

我覺得你這樣做是正確,它唯一缺少^$錨,以確保您的正則表達式的整個字符串相匹配。以here爲例。

相關問題