2015-11-06 66 views
1

我試圖構建一個正則表達式,但顯然是錯誤理解的東西。我有一個C#StackTrace,並希望實質上裁剪字符串的結尾,直到我看到我們的命名空間的第一個實例。以下是一部分數據說明 - 用手動定位的新行來說明我試圖匹配的位置。從字符串末尾匹配多個實例

at MooD.LandscapeExplorer.Controllers.LandscapeController.GetContextInstanceCount(BusinessContext context) in C:\Source\MooDEdge\Code\MooD16\MooD.LandscapeExplorer\Controllers\LandscapeController.cs:line 143 
    at System.Linq.Enumerable.<SelectManyIterator>d__1`2.MoveNext() 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 
    at MooD.LandscapeExplorer.Controllers.LandscapeController.ProcessContext(String[] types, String[] instances, QueryFilter[] filters) in C:\Source\MooDEdge\Code\MooD16\MooD.LandscapeExplorer\Controllers\LandscapeController.cs:line 125 

    at lambda_method(Closure , ControllerBase , Object[]) 
    at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) 
    at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
    at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
    at System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod() 

所以我想保持前半部分,從字符串中刪除下半年。我使用了負面預測(我從另一個問題中獲得,我不太瞭解它是如何工作的),以匹配除MooD以外的任何其他問題。然後我卡住了字符串$的末尾。

(at (?!MooD).*)$

在這一點上我以爲所有我需要做的是增加一個*匹配許多前一組的,把正則表達式爲:

(at (?!MooD).*)*$

然而這並未」如我在https://regex101.com/上測試時所預期的那樣工作。它仍然只是匹配最終的實例。我也嘗試添加一個新的在線檢測,但仍然只匹配的最後一行:

(at (?!MooD).*\n?)*$

任何人都可以解釋我如何能匹配休息,爲什麼這個解決方案不起作用?

+1

難道你不只是把所有的東西都分開回車,然後(倒退)放棄每一行,直到你打開包含MooD?正則表達式似乎矯枉過正你想要的 – Liam

回答

2

爲了配合底部,您可以使用該負前瞻基於正則表達式:

at (?:(?!MooD)[\s\S])*$ 

(?:(?!MooD)[\s\S])*將匹配0或多個任意字符,同時聲明,任何角色都有MooD的下一個位置。

[\s\S]將匹配任何字符,包括換行符。

PS:它是安全使用單詞邊界:

at (?:(?!\bMooD\b)[\s\S])*$ 

RegEx Demo

+0

我打算接受基於你鏈接到的RegEx演示 - 然後發現JavaScript不支持單行選項:( – Ian

+0

該死的,不知何故,我記住了Java。無論如何它可以是 – anubhava

+0

謝謝 - 此刻嘗試JavaScript與組'無效正則表達式:/(?s)at(?:(?!MooD)[\ s \ S])* /:Invalid group'。我猜這不是RegEx的完全實現版本 – Ian

0

我知道你想用正則表達式來做到這一點,但這裏是一個非正則表達式選項:

public static string GetMooDStackTrace(string stackTrace) 
{ 
    var lines = stackTrace.Split('\n'); 
    int lastLineWithMood = -1; 

    for (int i = 0; i < lines.Length; i++) 
    { 
     if (lines[i].Contains("MooD")) 
      lastLineWithMood = i; 
    } 

    return string.Join("\n", lines, 0, lastLineWithMood + 1); 
} 

從您的輸入中產生:

 
at MooD.LandscapeExplorer.Controllers.LandscapeController.GetContextInstanceCount(BusinessContext context) in C:\Source\MooDEdge\Code\MooD16\MooD.LandscapeExplorer\Controllers\LandscapeController.cs:line 143 
    at System.Linq.Enumerable.d__1`2.MoveNext() 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 
    at MooD.LandscapeExplorer.Controllers.LandscapeController.ProcessContext(String[] types, String[] instances, QueryFilter[] filters) in C:\Source\MooDEdge\Code\MooD16\MooD.LandscapeExplorer\Controllers\LandscapeController.cs:line 125 
+0

對不起 - 我不清楚RegEx正在JavaScript中執行。 – Ian

+0

應該比較容易移植,但我不熟悉JS,所以我不會嘗試。我想我會留給後代。 –

+0

是的 - 我發現它可能對其他人有用 – Ian