2011-04-08 94 views
2

我必須在另一個字符串(乾草堆)內找到特定「大括號」之間不發生的特定字符串(針)的出現。C#正則表達式匹配特定區域外的匹配

例如,考慮這個乾草堆: 「開始的東西結束一些其他的事情開始的東西結束還有更多的東西。」 而這種針: 「一些」 隨着我想找到不花括號之間的所有針在大括號「BEGIN」和「END」

。 (有兩個匹配:「一些」後面跟着「其他」和「一些」後面跟着「更多」)

我想我可以使用帶有負向望遠鏡/ lookbehind的正則表達式解決這個問題,但是怎麼做?

我已經試過

(?<!(BEGIN))some(?!(END)) 

這給了我4場比賽(顯然是因爲沒有 「一定」 是直接封閉之間的 「開始」 和 「結束」)

我也試過

(?<!(BEGIN.*))some(?!(.*END)) 

但是這樣根本沒有匹配(顯然是因爲每個針頭都以某種方式先於「BEGIN」)

不,我被卡住了。

這是我使用了最新的C#代碼:

string input = "BEGIN something END some other thing BEGIN something else END yet some more things."; 
global::System.Text.RegularExpressions.Regex re = new Regex(@"(?<!(BEGIN.*))some(?!(.*END))"); 
global::System.Text.RegularExpressions.MatchCollection matches = re.Matches(input); 
global::NUnit.Framework.Assert.AreEqual(2, matches.Count); 
+0

除了使用正則表達式之外,您是如何嘗試其他解決方案的? – jfs 2011-04-08 15:49:37

回答

1

將這樣的事情對你的工作:

(?:^|END)((?!BEGIN).*?)(some)(.*?)(?:BEGIN|$) 

這似乎文本匹配,因爲我測試使用RegExDesigner.NET。

+0

上面的表達它!非常感謝。我只需要得到Group [2] .Value而不是Group [0] .Value,但沒關係。也感謝提及RegExDesigner。我以前沒聽說過。 – miasbeck 2011-04-08 16:27:23

+0

我認爲這個表達式不起作用,如果你在同一個'end'和'begin'之間有多個'some'' - 「有些END會開始一些」 – Kobi 2011-04-08 16:43:01

0

您可以嘗試在BEGIN和END的出現分裂的字符串,這樣就可以確保只有一個BEGIN和字符串中的一端,你將你的正則表達式應用於。此外,如果您正在尋找BEGIN/END括號外的某些事件,那麼我認爲您應該向後看END並向前看(BEGIN)(正面向前/向後),與您所擁有的相反。

希望這會有所幫助。

0

如果你只是處理整個草垛而忽略乾草是在括號(是我推的比喻太遠?)

之間。例如,通過所有的標記看(或字符,如果你需要去那個級別)並尋找你的大括號。當找到開頭的時候,你會循環直到找到右大括號。此時,你開始尋找你的針,直到你找到另一個開口支撐。它的代碼比正則表達式多一點,但可能更易讀,更容易排除故障。

1

一個簡單的選擇是跳過你不想匹配的部分,僅捕獲您需要的針:

MatchCollection matches = Regex.Matches(input, "BEGIN.*?END|(?<Needle>some)"); 

你會得到兩個「一定」是你的就是後在所有匹配中取得成功的「Needle」組:

IEnumerable<Group> needles = matches.Cast<Match>() 
            .Select(m => m.Groups["Needle"]) 
            .Where(g => g.Success); 
+0

+1,這很聰明。你測試過了嗎?我可以告訴你的想法是,交替運算符('|')會使任何匹配'BEGIN。*?END'的東西與捕獲組短路,但我並不認爲交替是正則表達式中的短路。 – 2011-04-08 20:04:25

+0

更新:它確實有效。 http://rubular.com/r/6mKSumbyuF。我一定會記住這個訣竅。 – 2011-04-08 20:08:00

+0

@Justin - 謝謝!這不是關於短路,而是關於匹配引擎的工作方式 - 如果它找到了匹配「開始 - 結束」模塊,則它不會搜索並捕獲「some」。我有一些解釋[這裏](http://stackoverflow.com/questions/5153980/#5154081),[這裏](http://stackoverflow.com/questions/4383068/4384901#4384901)和[這裏] (http://stackoverflow.com/questions/5283269/#5288185)。 – Kobi 2011-04-08 21:54:24