2010-03-30 159 views
10

我需要從字符串中獲取所有子字符串。
對於前:
查找兩個字符串之間的所有子字符串

StringParser.GetSubstrings("[start]aaaaaa[end] wwwww [start]cccccc[end]", "[start]", "[end]"); 

返回2串 「AAAAAA」 和 「CCCCCC」 假設我們只有一個級別嵌套。 不知道有關正則表達式,但我認爲它將是有用的。

+0

1級'[開始] XXX [開始] YYY [結束] ZZZ [結束]'是可能的? – kennytm 2010-03-30 20:17:02

+0

這是不可能的。 – 2010-03-30 20:19:42

+0

如果你這樣做是爲了解析HTML或XML,有更好的方法... – Randolpho 2010-03-30 20:22:19

回答

31
private IEnumerable<string> GetSubStrings(string input, string start, string end) 
{ 
    Regex r = new Regex(Regex.Escape(start) + "(.*?)" + Regex.Escape(end)); 
    MatchCollection matches = r.Matches(input); 
    foreach (Match match in matches) 
     yield return match.Groups[1].Value; 
} 
+0

確切的我需要什麼,謝謝 – 2010-03-30 20:28:05

+3

+1 - 尤其是Regex.Escape :) – 2010-03-30 20:34:35

2

您將需要更好地定義管理您的匹配需求的規則。在構建任何類型的匹配或搜索代碼時,您需要清楚地瞭解您預期哪些輸入以及需要生成哪些輸出。如果不仔細考慮這些問題,那麼生成錯誤代碼是非常容易的。這就是說...

你應該可以使用正則表達式。嵌套可能會使它稍微複雜一些,但仍然可行(取決於您期望在嵌套場景中匹配的內容)。類似的東西應該讓你開始:

var start = "[start]"; 
var end = "[end]"; 
var regEx = new Regex(String.Format("{0}(.*){1}", Regex.Escape(start), Regex.Escape(end))); 
var source = "[start]aaaaaa[end] wwwww [start]cccccc[end]"; 
var matches = regEx.Match(source); 

將上面的代碼包裝成適合您需要的函數應該是微不足道的。

2

您可以使用正則表達式,但記得要打電話Regex.Escape你的論點:

public static IEnumerable<string> GetSubStrings(
    string text, 
    string start, 
    string end) 
{ 
    string regex = string.Format("{0}(.*?){1}", 
     Regex.Escape(start), 
     Regex.Escape(end)); 

    return Regex.Matches(text, regex, RegexOptions.Singleline) 
     .Cast<Match>() 
     .Select(match => match.Groups[1].Value); 
} 

我還添加了SingleLine選項,這樣它將匹配即使有新行文字。

4

下面是一個不使用正則表達式並且不考慮嵌套的解決方案。

public static IEnumerable<string> EnclosedStrings(
    this string s, 
    string begin, 
    string end) 
{ 
    int beginPos = s.IndexOf(begin, 0); 
    while (beginPos >= 0) 
    { 
     int start = beginPos + begin.Length; 
     int stop = s.IndexOf(end, start); 
     if (stop < 0) 
      yield break; 
     yield return s.Substring(start, stop - start); 
     beginPos = s.IndexOf(begin, stop+end.Length); 
    }   
} 
0

我很無聊,所以我做了一個無用的微基準,這「證明」(在我的數據集,其中有串起來的字符7K和<b>標籤的開始/結束參數)我懷疑juharr的解決方案是整體三者中速度最快的。

結果(1000000次迭代* 20測試用例):

juharr: 6371ms 
Jake: 6825ms 
Mark Byers: 82063ms 

注:編譯正則表達式並沒有加快速度多在我的數據集。

0

自由正則表達式-方法:嵌套裝置

public static List<string> extract_strings(string src, string start, string end) 
{ 
    if (src.IndexOf(start) > 0) 
    { 
     src = src.Substring(src.IndexOf(start)); 
    } 
    string[] array1 = src.Split(new[] { start }, StringSplitOptions.None); 
    List<string> list = new List<string>(); 
    foreach (string value in array1) 
    { 
     if (value.Contains(end)) 
     { 
      list.Add(value.Split(new[] { end }, StringSplitOptions.None)[0]); 
     } 
    } 
    return list; 
} 
相關問題