2012-12-08 98 views
9

我想開發將匹配兩個字符串之間的所有字符串的方法之間的所有字符串:提取兩個字符串

我已經試過這一點,但它僅返回第一個匹配:

string ExtractString(string s, string start,string end) 
     { 
      // You should check for errors in real-world code, omitted for brevity 

      int startIndex = s.IndexOf(start) + start.Length; 
      int endIndex = s.IndexOf(end, startIndex); 
      return s.Substring(startIndex, endIndex - startIndex); 
     } 

讓我們假設我們有這個字符串

String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2" 

我想用c#函數執行以下操作:

public List<string> ExtractFromString(String Text,String Start, String End) 
{ 
    List<string> Matched = new List<string>(); 
    . 
    . 
    . 
    return Matched; 
} 
// Example of use 

ExtractFromString("A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2","A1","A2") 

    // Will return : 
    // FIRSTSTRING 
    // SECONDSTRING 
    // THIRDSTRING 

謝謝你的幫助!

+0

你如何識別你的「價值」? – Douglas

+0

對不起,我不太清楚!這個想法是,字符串「A1」和字符串「A2」之間的所有字符串將被返回! – Anass

+5

嘗試使用正則表達式,將爲此完美工作:) – 2pietjuh2

回答

25
private static List<string> ExtractFromString(
    string text, string startString, string endString) 
{    
    List<string> matched = new List<string>(); 
    int indexStart = 0, indexEnd=0; 
    bool exit = false; 
    while(!exit) 
    { 
     indexStart = text.IndexOf(startString); 
     indexEnd = text.IndexOf(endString); 
     if (indexStart != -1 && indexEnd != -1) 
     { 
      matched.Add(text.Substring(indexStart + startString.Length, 
       indexEnd - indexStart - startString.Length)); 
      text = text.Substring(indexEnd + endString.Length); 
     } 
     else 
      exit = true; 
    } 
    return matched; 
} 
+1

感謝您的幫助! – Anass

+1

您的解決方案正在致謝! – Anass

+1

這個代碼拋出異常,如果endString是startString像以前一樣\ r \ n您必須indexStart –

1

可以使用在下面的代碼開始標識符字符串分割成一個數組:

String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"; 

String[] arr = str.Split("A1"); 

然後通過您的陣列迭代並刪除每個字符串的最後2個字符(以除去A2)。您還需要放棄第一個數組元素,因爲假設字符串以A1開頭,它將爲空。

代碼未經測試,目前在移動

+0

好主意!我會盡力讓你知道結果! :) – Anass

+0

謝謝扎伊德命題的作品!感謝您的幫助 ! – Anass

4
text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries); 
+4

後採取indexEnd這段代碼也將返回「akslakhflkshdflhksdf」 –

+0

就像一個魅力!謝謝 ! – Anass

+0

對不起弗拉維亞是正確的他的解決方案是工作! – Anass

9

這裏是使用RegEx的溶液。不要忘記包含以下使用語句。

using System.Text.RegularExpressions

它會正確地返回給定的開始和結束串之間只有文字。

將不予退還:

akslakhflkshdflhksdf 

將返回:

FIRSTSTRING 
SECONDSTRING 
THIRDSTRING 

它使用正則表達式模式[start string].+?[end string]

開始和結束串是轉義他們包含正則表達式特殊字符。

private static List<string> ExtractFromString(string source, string start, string end) 
    { 
     var results = new List<string>(); 

     string pattern = string.Format(
      "{0}({1}){2}", 
      Regex.Escape(start), 
      ".+?", 
      Regex.Escape(end)); 

     foreach (Match m in Regex.Matches(source, pattern)) 
     { 
      results.Add(m.Groups[1].Value); 
     } 

     return results; 
    } 

也許你認爲成字符串像這樣的擴展方法:

public static class StringExtensionMethods 
{ 
    public static List<string> EverythingBetween(this string source, string start, string end) 
    { 
     var results = new List<string>(); 

     string pattern = string.Format(
      "{0}({1}){2}", 
      Regex.Escape(start), 
      ".+?", 
      Regex.Escape(end)); 

     foreach (Match m in Regex.Matches(source, pattern)) 
     { 
      results.Add(m.Groups[1].Value); 
     } 

     return results; 
    } 
} 

用途:

string source = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"; 
string start = "A1"; 
string end = "A2"; 

List<string> results = source.EverythingBetween(start, end); 
+0

如果添加perenthesis' 「{0}({1}){2}」'的模式,你可以使用'Match.Groups [1]'來獲取值 –

+1

+1教我的'+?' –

+1

感謝您的回答!我不得不用「的foreach(賽米......」(而不是變種M)爲它工作,它通過其他方式錯誤。 –

0

這是一個通用的解決方案,我相信更可讀的代碼。沒有測試過,所以要小心。

public static IEnumerable<IList<T>> SplitBy<T>(this IEnumerable<T> source, 
               Func<T, bool> startPredicate, 
               Func<T, bool> endPredicate, 
               bool includeDelimiter) 
{ 
    var l = new List<T>(); 
    foreach (var s in source) 
    { 
     if (startPredicate(s)) 
     { 
      if (l.Any()) 
      { 
       l = new List<T>(); 
      } 
      l.Add(s); 
     } 
     else if (l.Any()) 
     { 
      l.Add(s); 
     } 

     if (endPredicate(s)) 
     { 
      if (includeDelimiter) 
       yield return l; 
      else 
       yield return l.GetRange(1, l.Count - 2); 

      l = new List<T>(); 
     } 
    } 
} 

在你的情況,你可以打電話,

var text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"; 
var splits = text.SplitBy(x => x == "A1", x => x == "A2", false); 

這不是最有效的,當你不希望被包含在分隔符(如你的情況)的結果,但有效的相反情況。爲了加速你的情況,你可以直接調用GetEnumerator並使用MoveNext。

相關問題