Extrae todas las cadenas entre dos cadenas

Estoy tratando de desarrollar un método que combine todas las cadenas entre dos cadenas:

Intenté esto pero devuelve solo el primer partido:

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

Supongamos que tenemos esta cadena

 String Text = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2" 

Me gustaría la función ac # haciendo lo siguiente:

 public List ExtractFromString(String Text,String Start, String End) { List Matched = new List(); . . . return Matched; } // Example of use ExtractFromString("A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2","A1","A2") // Will return : // FIRSTSTRING // SECONDSTRING // THIRDSTRING 

Gracias por tu ayuda !

 private static List ExtractFromString( string text, string startString, string endString) { List matched = new List(); 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; } 

Aquí hay una solución usando RegEx. No olvide incluir la siguiente statement de uso.

using System.Text.RegularExpressions

Devolverá correctamente solo el texto entre las cadenas de inicio y fin dadas.

No será devuelto:

 akslakhflkshdflhksdf 

Será devuelto:

 FIRSTSTRING SECONDSTRING THIRDSTRING 

Utiliza el patrón de expresión regular [start string].+?[end string]

Las cadenas de inicio y final se escapan en caso de que contengan caracteres especiales de expresiones regulares.

  private static List ExtractFromString(string source, string start, string end) { var results = new List(); 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; } 

Puedes hacer eso en un método de extensión de String como este:

 public static class StringExtensionMethods { public static List EverythingBetween(this string source, string start, string end) { var results = new List(); 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; } } 

Uso:

 string source = "A1FIRSTSTRINGA2A1SECONDSTRINGA2akslakhflkshdflhksdfA1THIRDSTRINGA2"; string start = "A1"; string end = "A2"; List results = source.EverythingBetween(start, end); 
 text.Split(new[] {"A1", "A2"}, StringSplitOptions.RemoveEmptyEntries); 

Puede dividir la cadena en una matriz usando el identificador de inicio en el siguiente código:

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

Luego itere a través de su matriz y elimine los últimos 2 caracteres de cada cadena (para eliminar la A2). También deberá descartar el primer elemento de la matriz, ya que estará vacío suponiendo que la cadena comience con A1.

El código no está probado, actualmente en un dispositivo móvil

Esta es una solución genérica , y creo que es un código más legible. No probado, así que ten cuidado.

 public static IEnumerable> SplitBy(this IEnumerable source, Func startPredicate, Func endPredicate, bool includeDelimiter) { var l = new List(); foreach (var s in source) { if (startPredicate(s)) { if (l.Any()) { l = new List(); } 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(); } } } 

En tu caso, puedes llamar,

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

Esto no es lo más eficiente cuando no desea que se incluya el delimitador (como su caso) en el resultado, pero eficiente para casos opuestos. Para acelerar su caso, puede llamar directamente al GetEnumerator y hacer uso de MoveNext.