2012-12-08 39 views
9

Tôi đang cố gắng để phát triển một phương pháp mà sẽ phù hợp với tất cả các chuỗi giữa hai chuỗi:Giải nén tất cả các chuỗi giữa hai chuỗi

Tôi đã thử điều này, nhưng nó chỉ trả về các trận đấu đầu tiên:

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); 
     } 

giả sử chúng ta có chuỗi này

String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2" 

tôi muốn # chức năng ac làm như sau:

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 

Cảm ơn sự giúp đỡ của bạn!

+0

Làm cách nào để bạn xác định "giá trị" của mình? – Douglas

+0

Xin lỗi tôi không quá rõ ràng! Ý tưởng là tất cả các chuỗi giữa chuỗi "A1" và chuỗi "A2" sẽ được trả về! – Anass

+5

thử sử dụng cụm từ thông dụng, sẽ hoạt động hoàn hảo cho việc này :) – 2pietjuh2

Trả lời

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

Cảm ơn sự giúp đỡ của bạn! – Anass

+1

Giải pháp của bạn là cảm ơn! – Anass

+1

mã này ném ngoại lệ nếu endString là trước startString như \ r \ n bạn phải lấy indexEnd sau khi indexStart –

1

Bạn có thể chia chuỗi thành một mảng bằng cách sử dụng định danh bắt đầu trong đoạn mã sau:

String str = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"; 

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

Sau đó lặp qua mảng của bạn và loại bỏ các 2 ký tự cuối cùng của mỗi chuỗi (để loại bỏ các A2). Bạn cũng sẽ cần phải loại bỏ phần tử mảng đầu tiên vì nó sẽ trống rỗng giả sử chuỗi bắt đầu bằng A1.

Mã là chưa được kiểm tra, hiện nay trên điện thoại di động

+0

Ý tưởng hay! Tôi sẽ cố gắng và cho bạn biết kết quả! :) – Anass

+0

Cảm ơn Zaid Proposition hoạt động! cảm ơn sự giúp đỡ của bạn ! – Anass

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

mã này cũng sẽ trả về "akslakhflkshdflhksdf" –

+0

Giống như một sự quyến rũ! cảm ơn ! – Anass

+0

Xin lỗi Flavia đúng là giải pháp của anh ấy đang hoạt động! – Anass

9

Đây là một giải pháp sử dụng RegEx. Đừng quên bao gồm câu lệnh sử dụng sau đây.

using System.Text.RegularExpressions

Nó sẽ trở lại một cách chính xác chỉ văn bản giữa đầu và cuối chuỗi đã chọn.

sẽ không được trả lại:

akslakhflkshdflhksdf 

sẽ được trả lại:

FIRSTSTRING 
SECONDSTRING 
THIRDSTRING 

Nó sử dụng các mẫu biểu thức chính quy [start string].+?[end string]

Sự bắt đầu và kết thúc chuỗi đang trốn trong trường hợp chúng chứa các ký tự đặc biệt biểu thức chính quy.

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; 
    } 

Bạn có thể làm cho điều đó trở thành một phương pháp mở rộng của chuỗi như thế này:

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; 
    } 
} 

năng bảo mật bằng:

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

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

Nếu bạn thêm dấu ngoặc đơn '{0} ({1}) {2}" 'vào mẫu, bạn có thể sử dụng' Match.Groups [1] 'để lấy giá trị –

+1

Và +1 để dạy tôi' +? ' –

+1

Cảm ơn câu trả lời này! Tôi đã phải sử dụng "foreach (Match m ..." (thay vì var m) để nó hoạt động, nếu không nó sẽ gặp lỗi. –

0

Đây là một giải pháp chung, và tôi tin rằng mã dễ đọc hơn . Không được kiểm tra, vì vậy hãy cẩn thận.

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>(); 
     } 
    } 
} 

Trong trường hợp của bạn, bạn có thể gọi,

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

Đây không phải là hiệu quả nhất khi bạn không muốn các dấu phân cách để được bao gồm (như trường hợp của bạn) trong kết quả nhưng hiệu quả đối với trường hợp ngược lại. Để tăng tốc cho trường hợp của bạn, người dùng có thể gọi trực tiếp GetEnumerator và sử dụng MoveNext.

Các vấn đề liên quan