Wednesday, 22 October 2014

C# - How to Return a Substring Between Two Strings


Here is a non-RegEx solution for returning a substring between two strings in C#. I have also added a function for retrieving multiple occurrences which outputs as a List of strings.

The parameters called: includeFrom and includeUntil allow you to append the from and until fields to the result.


Usage:

Code Snippet
  1. // Example for one occurrences
  2. // This extracts 'Message Here' from this example chat log
  3. string message = "[12th July 2014] Message Here (Sent by Sean)".Substring(from: "]", until: "(", includeFrom: false, includeUntil: false);
  4. // Example for multiple occurances
  5. // This extracts all of the names which are enclosed between single quotes
  6. List<string> listOfNames = "'sean' random text 'dave' 355353 'jane' some text here 'tom'".SubstringAll(from: "'", until: "'");
End of Code Snippet



The Code:
Code Snippet
  1. /// <summary>
  2. /// Returns a substring between two anchor strings
  3. /// If from is null - Start of the string until the Second anchor
  4. /// If until is null - First anchor to the end of the string is returned
  5. /// </summary>
  6. /// <param name="this">Input string</param>
  7. /// <param name="from">An optional string to search after</param>
  8. /// <param name="until">An optional string to search before</param>
  9. /// <param name="includeFrom">Include from in the result</param>
  10. /// <param name="includeUntil">Include until in the result</param>
  11. /// <param name="comparison">An optional comparison for the search</param>
  12. /// <returns>A substring based on the search</returns>
  13. public static string Substring(this string @this, string from = null, string until = null, bool includeFrom = false, bool includeUntil = false, StringComparison comparison = StringComparison.InvariantCulture)
  14. {
  15.     var fromLength = (from ?? string.Empty).Length;
  16.     var startIndex = !string.IsNullOrEmpty(from)
  17.         ? @this.IndexOf(from, comparison) + fromLength
  18.         : 0;
  19.  
  20.     if (startIndex < fromLength) { return string.Empty; }
  21.  
  22.     var endIndex = !string.IsNullOrEmpty(until)
  23.     ? @this.IndexOf(until, startIndex, comparison)
  24.     : @this.Length;
  25.  
  26.     if (endIndex < 0) { return string.Empty; }
  27.  
  28.     if (includeFrom) // Do these AFTER start and end have been calculated
  29.         startIndex -= from.Length;
  30.     if (includeUntil)
  31.         endIndex += until.Length;
  32.  
  33.     return @this.Substring(startIndex, endIndex - startIndex);
  34. }
  35.  
  36. /// <summary>
  37. /// Returns a List of substrings between two anchor strings
  38. /// If from is null - Start of the string until the Second anchor
  39. /// If until is null - First anchor to the end of the string is returned
  40. /// </summary>
  41. /// <param name="this">Input string</param>
  42. /// <param name="from">An optional string to search after</param>
  43. /// <param name="until">An optional string to search before</param>
  44. /// <param name="includeFrom">Include from in the result</param>
  45. /// <param name="includeUntil">Include until in the result</param>
  46. /// <param name="skipEmptyResults">If empty results are found, then they are not added to the result set.</param>
  47. /// <param name="comparison">An optional comparison for the search</param>
  48. /// <returns>A List of substrings based on the search</returns>
  49. public static List<string> SubstringAll(this string @this, string from = null, string until = null, bool includeFrom = false, bool includeUntil = false, bool skipEmptyResults = true, StringComparison comparison = StringComparison.InvariantCulture)
  50. {
  51.     List<string> result = new List<string>();
  52.     try
  53.     {
  54.         while (true)
  55.         {
  56.             string res = @this.SubstringEx(from, until, includeFrom, includeUntil, comparison);
  57.  
  58.             if (!skipEmptyResults || !string.IsNullOrEmpty(res)) // Skip empty result sets
  59.                 result.Add(res);
  60.  
  61.             res = (!includeFrom) ? from + res : res;
  62.  
  63.             // If from and until are the same, then we can end up with problems and only returning half the result set. This fixes that problem.
  64.             if (from != until)
  65.                 res = (!includeUntil) ? res + until : res;
  66.  
  67.             @this = @this.Replace(res, string.Empty);
  68.         }
  69.     }
  70.     catch { }
  71.  
  72.     return result;
  73. }
End of Code Snippet

No comments: